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 2018/11/09 14:52:57 UTC

[01/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Repository: hbase-site
Updated Branches:
  refs/heads/asf-site c21eba909 -> 9592fdb58


http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
index 006d1ba..18cf507 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
@@ -654,258 +654,274 @@
 <span class="sourceLineNo">646</span>    }<a name="line.646"></a>
 <span class="sourceLineNo">647</span>  }<a name="line.647"></a>
 <span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>  /**<a name="line.649"></a>
-<span class="sourceLineNo">650</span>   * Add a peer and wait for it to initialize<a name="line.650"></a>
-<span class="sourceLineNo">651</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.651"></a>
-<span class="sourceLineNo">652</span>   */<a name="line.652"></a>
-<span class="sourceLineNo">653</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.653"></a>
-<span class="sourceLineNo">654</span>      final boolean waitForSource) throws Exception {<a name="line.654"></a>
-<span class="sourceLineNo">655</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>    try {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      manager.addPeer(peerId);<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    } catch (Exception e) {<a name="line.659"></a>
-<span class="sourceLineNo">660</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>    waitPeer(peerId, manager, waitForSource);<a name="line.662"></a>
-<span class="sourceLineNo">663</span>    if (managerOfCluster != null) {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      managerOfCluster.addPeer(peerId);<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>  }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>  private static void waitPeer(final String peerId,<a name="line.669"></a>
-<span class="sourceLineNo">670</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>      if (waitForSource) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>        if (rs == null) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          return false;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        }<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.678"></a>
-<span class="sourceLineNo">679</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>        return true;<a name="line.681"></a>
-<span class="sourceLineNo">682</span>      } else {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>        return (rp.getPeer(peerId) != null);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      }<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    });<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>  /**<a name="line.688"></a>
-<span class="sourceLineNo">689</span>   * Remove a peer and wait for it to get cleaned up<a name="line.689"></a>
-<span class="sourceLineNo">690</span>   * @param peerId<a name="line.690"></a>
-<span class="sourceLineNo">691</span>   * @throws Exception<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      try {<a name="line.697"></a>
-<span class="sourceLineNo">698</span>        manager.removePeer(peerId);<a name="line.698"></a>
-<span class="sourceLineNo">699</span>      } catch (Exception e) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        // ignore the failed exception and continue.<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      }<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      @Override<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      public boolean evaluate() throws Exception {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<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>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.713"></a>
-<span class="sourceLineNo">714</span>    // 1. Create store files for the families<a name="line.714"></a>
-<span class="sourceLineNo">715</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.718"></a>
-<span class="sourceLineNo">719</span>    p.add(hfilePath1);<a name="line.719"></a>
-<span class="sourceLineNo">720</span>    try {<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    } catch (IOException e) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    }<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    storeFiles.put(f1, p);<a name="line.726"></a>
-<span class="sourceLineNo">727</span>    scope.put(f1, 1);<a name="line.727"></a>
-<span class="sourceLineNo">728</span>    p = new ArrayList&lt;&gt;(1);<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.729"></a>
-<span class="sourceLineNo">730</span>    p.add(hfilePath2);<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    try {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    } catch (IOException e) {<a name="line.733"></a>
-<span class="sourceLineNo">734</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>    storeFiles.put(f2, p);<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    // 2. Create bulk load descriptor<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    BulkLoadDescriptor desc =<a name="line.739"></a>
-<span class="sourceLineNo">740</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.740"></a>
-<span class="sourceLineNo">741</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.741"></a>
-<span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    // 3. create bulk load wal edit event<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    return logEdit;<a name="line.745"></a>
-<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>  static class DummyNodeFailoverWorker extends Thread {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    Server server;<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    private ServerName deadRS;<a name="line.751"></a>
-<span class="sourceLineNo">752</span>    ReplicationQueueStorage rq;<a name="line.752"></a>
-<span class="sourceLineNo">753</span><a name="line.753"></a>
-<span class="sourceLineNo">754</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      this.deadRS = deadRS;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      this.server = s;<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.757"></a>
-<span class="sourceLineNo">758</span>        server.getConfiguration());<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>    @Override<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    public void run() {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>      try {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.764"></a>
-<span class="sourceLineNo">765</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>        for (String queue : queues) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.768"></a>
-<span class="sourceLineNo">769</span>          if (pair != null) {<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>      } catch (Exception e) {<a name="line.774"></a>
-<span class="sourceLineNo">775</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      } finally {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>        latch.countDown();<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    /**<a name="line.781"></a>
-<span class="sourceLineNo">782</span>     * @return 1 when the map is not empty.<a name="line.782"></a>
-<span class="sourceLineNo">783</span>     */<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    private int isLogZnodesMapPopulated() {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>      if (sets.size() &gt; 1) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      }<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (sets.size() == 1) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.790"></a>
-<span class="sourceLineNo">791</span>        for (String file : files) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>          // at least one file was missing<a name="line.792"></a>
-<span class="sourceLineNo">793</span>          if (!s.contains(file)) {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>            return 0;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>          }<a name="line.795"></a>
-<span class="sourceLineNo">796</span>        }<a name="line.796"></a>
-<span class="sourceLineNo">797</span>        return 1; // we found all the files<a name="line.797"></a>
-<span class="sourceLineNo">798</span>      }<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return 0;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span><a name="line.802"></a>
-<span class="sourceLineNo">803</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.803"></a>
-<span class="sourceLineNo">804</span><a name="line.804"></a>
-<span class="sourceLineNo">805</span>    @Override<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.808"></a>
-<span class="sourceLineNo">809</span>        throws IOException {<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      throw new IOException("Failing deliberately");<a name="line.810"></a>
-<span class="sourceLineNo">811</span>    }<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>  static class DummyServer implements Server {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    String hostname;<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>    DummyServer() {<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      hostname = "hostname.example.org";<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    }<a name="line.819"></a>
+<span class="sourceLineNo">649</span>  @Test<a name="line.649"></a>
+<span class="sourceLineNo">650</span>  public void testSameWALPrefix() throws IOException {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    Set&lt;String&gt; latestWalsBefore =<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      manager.getLastestPath().stream().map(Path::getName).collect(Collectors.toSet());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    String walName1 = "localhost,8080,12345-45678-Peer.34567";<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    String walName2 = "localhost,8080,12345.56789";<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    manager.preLogRoll(new Path(walName1));<a name="line.655"></a>
+<span class="sourceLineNo">656</span>    manager.preLogRoll(new Path(walName2));<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>    Set&lt;String&gt; latestWals = manager.getLastestPath().stream().map(Path::getName)<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      .filter(n -&gt; !latestWalsBefore.contains(n)).collect(Collectors.toSet());<a name="line.659"></a>
+<span class="sourceLineNo">660</span>    assertEquals(2, latestWals.size());<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    assertTrue(latestWals.contains(walName1));<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    assertTrue(latestWals.contains(walName2));<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  /**<a name="line.665"></a>
+<span class="sourceLineNo">666</span>   * Add a peer and wait for it to initialize<a name="line.666"></a>
+<span class="sourceLineNo">667</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.667"></a>
+<span class="sourceLineNo">668</span>   */<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.669"></a>
+<span class="sourceLineNo">670</span>      final boolean waitForSource) throws Exception {<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    try {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      manager.addPeer(peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    } catch (Exception e) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    waitPeer(peerId, manager, waitForSource);<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    if (managerOfCluster != null) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      managerOfCluster.addPeer(peerId);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    }<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>  private static void waitPeer(final String peerId,<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.688"></a>
+<span class="sourceLineNo">689</span>      if (waitForSource) {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        if (rs == null) {<a name="line.691"></a>
+<span class="sourceLineNo">692</span>          return false;<a name="line.692"></a>
+<span class="sourceLineNo">693</span>        }<a name="line.693"></a>
+<span class="sourceLineNo">694</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.695"></a>
+<span class="sourceLineNo">696</span>        }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>        return true;<a name="line.697"></a>
+<span class="sourceLineNo">698</span>      } else {<a name="line.698"></a>
+<span class="sourceLineNo">699</span>        return (rp.getPeer(peerId) != null);<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      }<a name="line.700"></a>
+<span class="sourceLineNo">701</span>    });<a name="line.701"></a>
+<span class="sourceLineNo">702</span>  }<a name="line.702"></a>
+<span class="sourceLineNo">703</span><a name="line.703"></a>
+<span class="sourceLineNo">704</span>  /**<a name="line.704"></a>
+<span class="sourceLineNo">705</span>   * Remove a peer and wait for it to get cleaned up<a name="line.705"></a>
+<span class="sourceLineNo">706</span>   * @param peerId<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * @throws Exception<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   */<a name="line.708"></a>
+<span class="sourceLineNo">709</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.709"></a>
+<span class="sourceLineNo">710</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.711"></a>
+<span class="sourceLineNo">712</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.712"></a>
+<span class="sourceLineNo">713</span>      try {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>        manager.removePeer(peerId);<a name="line.714"></a>
+<span class="sourceLineNo">715</span>      } catch (Exception e) {<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        // ignore the failed exception and continue.<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      }<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    }<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      @Override<a name="line.720"></a>
+<span class="sourceLineNo">721</span>      public boolean evaluate() throws Exception {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.722"></a>
+<span class="sourceLineNo">723</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.723"></a>
+<span class="sourceLineNo">724</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      }<a name="line.725"></a>
+<span class="sourceLineNo">726</span>    });<a name="line.726"></a>
+<span class="sourceLineNo">727</span>  }<a name="line.727"></a>
+<span class="sourceLineNo">728</span><a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    // 1. Create store files for the families<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.731"></a>
+<span class="sourceLineNo">732</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    p.add(hfilePath1);<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    try {<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    } catch (IOException e) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>    storeFiles.put(f1, p);<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    scope.put(f1, 1);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    p = new ArrayList&lt;&gt;(1);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.745"></a>
+<span class="sourceLineNo">746</span>    p.add(hfilePath2);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    try {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    } catch (IOException e) {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    }<a name="line.752"></a>
+<span class="sourceLineNo">753</span>    storeFiles.put(f2, p);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // 2. Create bulk load descriptor<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    BulkLoadDescriptor desc =<a name="line.755"></a>
+<span class="sourceLineNo">756</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.757"></a>
+<span class="sourceLineNo">758</span><a name="line.758"></a>
+<span class="sourceLineNo">759</span>    // 3. create bulk load wal edit event<a name="line.759"></a>
+<span class="sourceLineNo">760</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.760"></a>
+<span class="sourceLineNo">761</span>    return logEdit;<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>  static class DummyNodeFailoverWorker extends Thread {<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    Server server;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    private ServerName deadRS;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    ReplicationQueueStorage rq;<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      this.deadRS = deadRS;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      this.server = s;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        server.getConfiguration());<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    }<a name="line.775"></a>
+<span class="sourceLineNo">776</span><a name="line.776"></a>
+<span class="sourceLineNo">777</span>    @Override<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    public void run() {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>      try {<a name="line.779"></a>
+<span class="sourceLineNo">780</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.780"></a>
+<span class="sourceLineNo">781</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.781"></a>
+<span class="sourceLineNo">782</span>        for (String queue : queues) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.783"></a>
+<span class="sourceLineNo">784</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.784"></a>
+<span class="sourceLineNo">785</span>          if (pair != null) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.789"></a>
+<span class="sourceLineNo">790</span>      } catch (Exception e) {<a name="line.790"></a>
+<span class="sourceLineNo">791</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.791"></a>
+<span class="sourceLineNo">792</span>      } finally {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>        latch.countDown();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      }<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">796</span><a name="line.796"></a>
+<span class="sourceLineNo">797</span>    /**<a name="line.797"></a>
+<span class="sourceLineNo">798</span>     * @return 1 when the map is not empty.<a name="line.798"></a>
+<span class="sourceLineNo">799</span>     */<a name="line.799"></a>
+<span class="sourceLineNo">800</span>    private int isLogZnodesMapPopulated() {<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      if (sets.size() &gt; 1) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      }<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      if (sets.size() == 1) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        for (String file : files) {<a name="line.807"></a>
+<span class="sourceLineNo">808</span>          // at least one file was missing<a name="line.808"></a>
+<span class="sourceLineNo">809</span>          if (!s.contains(file)) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>            return 0;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>          }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        }<a name="line.812"></a>
+<span class="sourceLineNo">813</span>        return 1; // we found all the files<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      }<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      return 0;<a name="line.815"></a>
+<span class="sourceLineNo">816</span>    }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.819"></a>
 <span class="sourceLineNo">820</span><a name="line.820"></a>
-<span class="sourceLineNo">821</span>    DummyServer(String hostname) {<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      this.hostname = hostname;<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>    @Override<a name="line.825"></a>
-<span class="sourceLineNo">826</span>    public Configuration getConfiguration() {<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      return conf;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    }<a name="line.828"></a>
+<span class="sourceLineNo">821</span>    @Override<a name="line.821"></a>
+<span class="sourceLineNo">822</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.822"></a>
+<span class="sourceLineNo">823</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.823"></a>
+<span class="sourceLineNo">824</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.824"></a>
+<span class="sourceLineNo">825</span>        throws IOException {<a name="line.825"></a>
+<span class="sourceLineNo">826</span>      throw new IOException("Failing deliberately");<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    }<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    @Override<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    public ZKWatcher getZooKeeper() {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      return zkw;<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    }<a name="line.833"></a>
-<span class="sourceLineNo">834</span><a name="line.834"></a>
-<span class="sourceLineNo">835</span>    @Override<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>      return null;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>    }<a name="line.838"></a>
-<span class="sourceLineNo">839</span>    @Override<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    public ClusterConnection getConnection() {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      return null;<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span><a name="line.843"></a>
-<span class="sourceLineNo">844</span>    @Override<a name="line.844"></a>
-<span class="sourceLineNo">845</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.845"></a>
-<span class="sourceLineNo">846</span>      return null;<a name="line.846"></a>
-<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>    @Override<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    public ServerName getServerName() {<a name="line.850"></a>
-<span class="sourceLineNo">851</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    }<a name="line.852"></a>
-<span class="sourceLineNo">853</span><a name="line.853"></a>
-<span class="sourceLineNo">854</span>    @Override<a name="line.854"></a>
-<span class="sourceLineNo">855</span>    public void abort(String why, Throwable e) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    public boolean isAborted() {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      return false;<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>    @Override<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    public void stop(String why) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    }<a name="line.867"></a>
-<span class="sourceLineNo">868</span><a name="line.868"></a>
-<span class="sourceLineNo">869</span>    @Override<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    public boolean isStopped() {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    public ChoreService getChoreService() {<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      return null;<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    }<a name="line.877"></a>
-<span class="sourceLineNo">878</span><a name="line.878"></a>
-<span class="sourceLineNo">879</span>    @Override<a name="line.879"></a>
-<span class="sourceLineNo">880</span>    public ClusterConnection getClusterConnection() {<a name="line.880"></a>
-<span class="sourceLineNo">881</span>      // TODO Auto-generated method stub<a name="line.881"></a>
-<span class="sourceLineNo">882</span>      return null;<a name="line.882"></a>
+<span class="sourceLineNo">830</span>  static class DummyServer implements Server {<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    String hostname;<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>    DummyServer() {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>      hostname = "hostname.example.org";<a name="line.834"></a>
+<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
+<span class="sourceLineNo">836</span><a name="line.836"></a>
+<span class="sourceLineNo">837</span>    DummyServer(String hostname) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      this.hostname = hostname;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>    @Override<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    public Configuration getConfiguration() {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      return conf;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>    }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>    @Override<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    public ZKWatcher getZooKeeper() {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      return zkw;<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span><a name="line.850"></a>
+<span class="sourceLineNo">851</span>    @Override<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>      return null;<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    }<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    @Override<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    public ClusterConnection getConnection() {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      return null;<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>    @Override<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      return null;<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    }<a name="line.863"></a>
+<span class="sourceLineNo">864</span><a name="line.864"></a>
+<span class="sourceLineNo">865</span>    @Override<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    public ServerName getServerName() {<a name="line.866"></a>
+<span class="sourceLineNo">867</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    }<a name="line.868"></a>
+<span class="sourceLineNo">869</span><a name="line.869"></a>
+<span class="sourceLineNo">870</span>    @Override<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    public void abort(String why, Throwable e) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.872"></a>
+<span class="sourceLineNo">873</span>    }<a name="line.873"></a>
+<span class="sourceLineNo">874</span><a name="line.874"></a>
+<span class="sourceLineNo">875</span>    @Override<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    public boolean isAborted() {<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      return false;<a name="line.877"></a>
+<span class="sourceLineNo">878</span>    }<a name="line.878"></a>
+<span class="sourceLineNo">879</span><a name="line.879"></a>
+<span class="sourceLineNo">880</span>    @Override<a name="line.880"></a>
+<span class="sourceLineNo">881</span>    public void stop(String why) {<a name="line.881"></a>
+<span class="sourceLineNo">882</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.882"></a>
 <span class="sourceLineNo">883</span>    }<a name="line.883"></a>
 <span class="sourceLineNo">884</span><a name="line.884"></a>
 <span class="sourceLineNo">885</span>    @Override<a name="line.885"></a>
-<span class="sourceLineNo">886</span>    public FileSystem getFileSystem() {<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return null;<a name="line.887"></a>
+<span class="sourceLineNo">886</span>    public boolean isStopped() {<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    public boolean isStopping() {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      return false;<a name="line.892"></a>
+<span class="sourceLineNo">891</span>    public ChoreService getChoreService() {<a name="line.891"></a>
+<span class="sourceLineNo">892</span>      return null;<a name="line.892"></a>
 <span class="sourceLineNo">893</span>    }<a name="line.893"></a>
 <span class="sourceLineNo">894</span><a name="line.894"></a>
 <span class="sourceLineNo">895</span>    @Override<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.896"></a>
-<span class="sourceLineNo">897</span>      return null;<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">896</span>    public ClusterConnection getClusterConnection() {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // TODO Auto-generated method stub<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      return null;<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>    @Override<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    public FileSystem getFileSystem() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>      return null;<a name="line.903"></a>
+<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>    @Override<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    public boolean isStopping() {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      return false;<a name="line.908"></a>
+<span class="sourceLineNo">909</span>    }<a name="line.909"></a>
+<span class="sourceLineNo">910</span><a name="line.910"></a>
+<span class="sourceLineNo">911</span>    @Override<a name="line.911"></a>
+<span class="sourceLineNo">912</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>      return null;<a name="line.913"></a>
+<span class="sourceLineNo">914</span>    }<a name="line.914"></a>
+<span class="sourceLineNo">915</span>  }<a name="line.915"></a>
+<span class="sourceLineNo">916</span>}<a name="line.916"></a>
 
 
 


[20/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<

<TRUNCATED>

[15/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.TableSkewCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    

<TRUNCATED>

[21/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaCandidateGenerator.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.43

<TRUNCATED>

[36/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CPRequestCostFunction.html
----------------------------------------------------------------------
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 9d1542c..ec5f688 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
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    

<TRUNCATED>

[42/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html
index dff70dc..8ea34c4 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":17,"i1":6,"i2":6,"i3":17,"i4":17,"i5":17,"i6":17,"i7":17,"i8":17,"i9":17,"i10":6,"i11":6,"i12":6,"i13":6,"i14":6,"i15":6,"i16":6,"i17":6,"i18":17,"i19":17,"i20":6,"i21":17,"i22":6,"i23":17,"i24":17,"i25":17,"i26":6,"i27":6,"i28":6,"i29":6,"i30":17,"i31":17,"i32":17,"i33":17,"i34":17,"i35":17,"i36":17,"i37":17,"i38":17,"i39":17,"i40":17};
+var methods = {"i0":17,"i1":6,"i2":6,"i3":17,"i4":17,"i5":17,"i6":17,"i7":17,"i8":17,"i9":17,"i10":6,"i11":6,"i12":6,"i13":6,"i14":6,"i15":6,"i16":17,"i17":17,"i18":6,"i19":6,"i20":17,"i21":17,"i22":6,"i23":17,"i24":6,"i25":17,"i26":17,"i27":17,"i28":6,"i29":6,"i30":6,"i31":6,"i32":17,"i33":17,"i34":17,"i35":17,"i36":17,"i37":17,"i38":17,"i39":17,"i40":17,"i41":17,"i42":17};
 var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"],16:["t5","Default Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -106,7 +106,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Public
-public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.70">RegionInfo</a></pre>
+public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.72">RegionInfo</a></pre>
 <div class="block">Information about a region. A region is a range of keys in the whole keyspace
  of a table, an identifier (a timestamp) for differentiating between subset
  ranges (after region split) and a replicaId for differentiating the instance
@@ -293,68 +293,77 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString--">getRegionNameAsString</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i16" class="altColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a></span>(byte[]&nbsp;regionName)</code>&nbsp;</td>
+</tr>
+<tr id="i17" class="rowColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a></span>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
+                     byte[]&nbsp;regionName)</code>&nbsp;</td>
+</tr>
+<tr id="i18" class="altColor">
 <td class="colFirst"><code>int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getReplicaId--">getReplicaId</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i17" class="rowColor">
+<tr id="i19" class="rowColor">
 <td class="colFirst"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog--">getShortNameToLog</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i18" class="altColor">
+<tr id="i20" class="altColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a></span>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;ris)</code>&nbsp;</td>
 </tr>
-<tr id="i19" class="rowColor">
+<tr id="i21" class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a></span>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</code>&nbsp;</td>
 </tr>
-<tr id="i20" class="altColor">
+<tr id="i22" class="altColor">
 <td class="colFirst"><code>byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getStartKey--">getStartKey</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i21" class="rowColor">
+<tr id="i23" class="rowColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getStartKey-byte:A-">getStartKey</a></span>(byte[]&nbsp;regionName)</code>
 <div class="block">Gets the start key from the specified region name.</div>
 </td>
 </tr>
-<tr id="i22" class="altColor">
+<tr id="i24" class="altColor">
 <td class="colFirst"><code><a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getTable--">getTable</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i23" class="rowColor">
+<tr id="i25" class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getTable-byte:A-">getTable</a></span>(byte[]&nbsp;regionName)</code>
 <div class="block">Gets the table name from the specified region name.</div>
 </td>
 </tr>
-<tr id="i24" class="altColor">
+<tr id="i26" class="altColor">
 <td class="colFirst"><code>static boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a></span>(byte[]&nbsp;regionName)</code>
 <div class="block">Does region name contain its encoded name?</div>
 </td>
 </tr>
-<tr id="i25" class="rowColor">
+<tr id="i27" class="rowColor">
 <td class="colFirst"><code>static boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isEncodedRegionName-byte:A-">isEncodedRegionName</a></span>(byte[]&nbsp;regionName)</code>&nbsp;</td>
 </tr>
-<tr id="i26" class="altColor">
+<tr id="i28" class="altColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isMetaRegion--">isMetaRegion</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i27" class="rowColor">
+<tr id="i29" class="rowColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isOffline--">isOffline</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i28" class="altColor">
+<tr id="i30" class="altColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isSplit--">isSplit</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i29" class="rowColor">
+<tr id="i31" class="rowColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isSplitParent--">isSplitParent</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i30" class="altColor">
+<tr id="i32" class="altColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseDelimitedFrom-byte:A-int-int-">parseDelimitedFrom</a></span>(byte[]&nbsp;bytes,
                   int&nbsp;offset,
@@ -362,55 +371,55 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <div class="block">Parses all the RegionInfo instances from the passed in stream until EOF.</div>
 </td>
 </tr>
-<tr id="i31" class="rowColor">
+<tr id="i33" class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-">parseFrom</a></span>(byte[]&nbsp;bytes)</code>&nbsp;</td>
 </tr>
-<tr id="i32" class="altColor">
+<tr id="i34" class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-int-int-">parseFrom</a></span>(byte[]&nbsp;bytes,
          int&nbsp;offset,
          int&nbsp;len)</code>&nbsp;</td>
 </tr>
-<tr id="i33" class="rowColor">
+<tr id="i35" class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-java.io.DataInputStream-">parseFrom</a></span>(<a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html?is-external=true" title="class or interface in java.io">DataInputStream</a>&nbsp;in)</code>
 <div class="block">Parses an RegionInfo instance from the passed in stream.</div>
 </td>
 </tr>
-<tr id="i34" class="altColor">
+<tr id="i36" class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFromOrNull-byte:A-">parseFromOrNull</a></span>(byte[]&nbsp;bytes)</code>&nbsp;</td>
 </tr>
-<tr id="i35" class="rowColor">
+<tr id="i37" class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFromOrNull-byte:A-int-int-">parseFromOrNull</a></span>(byte[]&nbsp;bytes,
                int&nbsp;offset,
                int&nbsp;len)</code>&nbsp;</td>
 </tr>
-<tr id="i36" class="altColor">
+<tr id="i38" class="altColor">
 <td class="colFirst"><code>static byte[][]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseRegionName-byte:A-">parseRegionName</a></span>(byte[]&nbsp;regionName)</code>
 <div class="block">Separate elements of a regionName.</div>
 </td>
 </tr>
-<tr id="i37" class="rowColor">
+<tr id="i39" class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#prettyPrint-java.lang.String-">prettyPrint</a></span>(<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;encodedRegionName)</code>
 <div class="block">Use logging.</div>
 </td>
 </tr>
-<tr id="i38" class="altColor">
+<tr id="i40" class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a></span>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>&nbsp;</td>
 </tr>
-<tr id="i39" class="rowColor">
+<tr id="i41" class="rowColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a></span>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)</code>
 <div class="block">Serializes given RegionInfo's as a byte array.</div>
 </td>
 </tr>
-<tr id="i40" class="altColor">
+<tr id="i42" class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></span>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>
 <div class="block">Use this instead of <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when writing to a stream and you want to use
@@ -439,7 +448,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <li class="blockList">
 <h4>ENC_SEPARATOR</h4>
 <pre>@InterfaceAudience.Private
-static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.76">ENC_SEPARATOR</a></pre>
+static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.78">ENC_SEPARATOR</a></pre>
 <div class="block">Separator used to demarcate the encodedName in a region name
  in the new format. See description on new format above.</div>
 <dl>
@@ -455,7 +464,7 @@ static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/c
 <li class="blockList">
 <h4>MD5_HEX_LENGTH</h4>
 <pre>@InterfaceAudience.Private
-static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.79">MD5_HEX_LENGTH</a></pre>
+static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.81">MD5_HEX_LENGTH</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.client.RegionInfo.MD5_HEX_LENGTH">Constant Field Values</a></dd>
@@ -469,7 +478,7 @@ static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/c
 <li class="blockList">
 <h4>DEFAULT_REPLICA_ID</h4>
 <pre>@InterfaceAudience.Private
-static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.82">DEFAULT_REPLICA_ID</a></pre>
+static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.84">DEFAULT_REPLICA_ID</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID">Constant Field Values</a></dd>
@@ -483,7 +492,7 @@ static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/c
 <li class="blockList">
 <h4>REPLICA_ID_FORMAT</h4>
 <pre>@InterfaceAudience.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/client/RegionInfo.html#line.89">REPLICA_ID_FORMAT</a></pre>
+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/client/RegionInfo.html#line.91">REPLICA_ID_FORMAT</a></pre>
 <div class="block">to keep appended int's sorted in string format. Only allows 2 bytes
  to be sorted for replicaId.</div>
 <dl>
@@ -499,7 +508,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/S
 <li class="blockList">
 <h4>REPLICA_ID_DELIMITER</h4>
 <pre>@InterfaceAudience.Private
-static final&nbsp;byte <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.92">REPLICA_ID_DELIMITER</a></pre>
+static final&nbsp;byte <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.94">REPLICA_ID_DELIMITER</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.client.RegionInfo.REPLICA_ID_DELIMITER">Constant Field Values</a></dd>
@@ -513,7 +522,7 @@ static final&nbsp;byte <a href="../../../../../src-html/org/apache/hadoop/hbase/
 <li class="blockList">
 <h4>INVALID_REGION_NAME_FORMAT_MESSAGE</h4>
 <pre>@InterfaceAudience.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/client/RegionInfo.html#line.95">INVALID_REGION_NAME_FORMAT_MESSAGE</a></pre>
+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/client/RegionInfo.html#line.97">INVALID_REGION_NAME_FORMAT_MESSAGE</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.client.RegionInfo.INVALID_REGION_NAME_FORMAT_MESSAGE">Constant Field Values</a></dd>
@@ -527,7 +536,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/S
 <li class="blockList">
 <h4>COMPARATOR</h4>
 <pre>@InterfaceAudience.Private
-static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html?is-external=true" title="class or interface in java.util">Comparator</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.98">COMPARATOR</a></pre>
+static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html?is-external=true" title="class or interface in java.util">Comparator</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.100">COMPARATOR</a></pre>
 </li>
 </ul>
 </li>
@@ -544,7 +553,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.154">getShortNameToLog</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.156">getShortNameToLog</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a short, printable name for this region
@@ -558,7 +567,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionId</h4>
-<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.159">getRegionId</a>()</pre>
+<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.161">getRegionId</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the regionId.</dd>
@@ -571,7 +580,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionName</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.165">getRegionName</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.167">getRegionName</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the regionName as an array of bytes.</dd>
@@ -586,7 +595,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionNameAsString</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.170">getRegionNameAsString</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.172">getRegionNameAsString</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Region name as a String for use in logging, etc.</dd>
@@ -599,7 +608,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedName</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.175">getEncodedName</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.177">getEncodedName</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the encoded region name.</dd>
@@ -612,7 +621,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedNameAsBytes</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.180">getEncodedNameAsBytes</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.182">getEncodedNameAsBytes</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the encoded region name as an array of bytes.</dd>
@@ -625,7 +634,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartKey</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.185">getStartKey</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.187">getStartKey</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the startKey.</dd>
@@ -638,7 +647,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getEndKey</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.190">getEndKey</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.192">getEndKey</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the endKey.</dd>
@@ -651,7 +660,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getTable</h4>
-<pre><a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.195">getTable</a>()</pre>
+<pre><a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.197">getTable</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>current table name of the region</dd>
@@ -664,7 +673,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>getReplicaId</h4>
-<pre>int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.200">getReplicaId</a>()</pre>
+<pre>int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.202">getReplicaId</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>returns region replica id</dd>
@@ -677,7 +686,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplit</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.205">isSplit</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.207">isSplit</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if has been split and has daughters.</dd>
@@ -690,7 +699,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>isOffline</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.210">isOffline</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.212">isOffline</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if this region is offline.</dd>
@@ -703,7 +712,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplitParent</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.215">isSplitParent</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.217">isSplitParent</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if this is a split parent region.</dd>
@@ -716,7 +725,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>isMetaRegion</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.220">isMetaRegion</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.222">isMetaRegion</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>true if this region is a meta region.</dd>
@@ -729,7 +738,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRange</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.231">containsRange</a>(byte[]&nbsp;rangeStartKey,
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.233">containsRange</a>(byte[]&nbsp;rangeStartKey,
                       byte[]&nbsp;rangeEndKey)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -751,7 +760,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRow</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.237">containsRow</a>(byte[]&nbsp;row)</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.239">containsRow</a>(byte[]&nbsp;row)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>row</code> - </dd>
@@ -767,7 +776,7 @@ static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/C
 <li class="blockList">
 <h4>hasEncodedName</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.246">hasEncodedName</a>(byte[]&nbsp;regionName)</pre>
+static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.248">hasEncodedName</a>(byte[]&nbsp;regionName)</pre>
 <div class="block">Does region name contain its encoded name?</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -785,20 +794,42 @@ static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbas
 <li class="blockList">
 <h4>encodeRegionName</h4>
 <pre>@InterfaceAudience.Private
-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/client/RegionInfo.html#line.256">encodeRegionName</a>(byte[]&nbsp;regionName)</pre>
+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/client/RegionInfo.html#line.258">encodeRegionName</a>(byte[]&nbsp;regionName)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the encodedName</dd>
 </dl>
 </li>
 </ul>
+<a name="getRegionNameAsString-byte:A-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>getRegionNameAsString</h4>
+<pre>@InterfaceAudience.Private
+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/client/RegionInfo.html#line.277">getRegionNameAsString</a>(byte[]&nbsp;regionName)</pre>
+</li>
+</ul>
+<a name="getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>getRegionNameAsString</h4>
+<pre>@InterfaceAudience.Private
+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/client/RegionInfo.html#line.282">getRegionNameAsString</a>(@CheckForNull
+                                                               <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
+                                                               byte[]&nbsp;regionName)</pre>
+</li>
+</ul>
 <a name="getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre>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/client/RegionInfo.html#line.278">getShortNameToLog</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</pre>
+<pre>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/client/RegionInfo.html#line.300">getShortNameToLog</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a String of short, printable names for <code>hris</code>
@@ -812,7 +843,7 @@ static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre>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/client/RegionInfo.html#line.286">getShortNameToLog</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;ris)</pre>
+<pre>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/client/RegionInfo.html#line.308">getShortNameToLog</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;ris)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a String of short, printable names for <code>hris</code>
@@ -827,7 +858,7 @@ static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.
 <li class="blockList">
 <h4>getTable</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.300">getTable</a>(byte[]&nbsp;regionName)</pre>
+static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.322">getTable</a>(byte[]&nbsp;regionName)</pre>
 <div class="block">Gets the table name from the specified region name.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -843,7 +874,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" titl
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartKey</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.322">getStartKey</a>(byte[]&nbsp;regionName)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.344">getStartKey</a>(byte[]&nbsp;regionName)
                    throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Gets the start key from the specified region name.</div>
 <dl>
@@ -863,7 +894,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" titl
 <li class="blockList">
 <h4>isEncodedRegionName</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.327">isEncodedRegionName</a>(byte[]&nbsp;regionName)
+static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.349">isEncodedRegionName</a>(byte[]&nbsp;regionName)
                                                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -878,7 +909,7 @@ static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbas
 <li class="blockList">
 <h4>parseFromOrNull</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.346">parseFromOrNull</a>(byte[]&nbsp;bytes)</pre>
+static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.368">parseFromOrNull</a>(byte[]&nbsp;bytes)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>bytes</code> - </dd>
@@ -895,7 +926,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <li class="blockList">
 <h4>parseFromOrNull</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.359">parseFromOrNull</a>(byte[]&nbsp;bytes,
+static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.381">parseFromOrNull</a>(byte[]&nbsp;bytes,
                                                              int&nbsp;offset,
                                                              int&nbsp;len)</pre>
 <dl>
@@ -916,7 +947,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <li class="blockList">
 <h4>parseFrom</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.374">parseFrom</a>(byte[]&nbsp;bytes)
+static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.396">parseFrom</a>(byte[]&nbsp;bytes)
                                                 throws <a href="../../../../../org/apache/hadoop/hbase/exceptions/DeserializationException.html" title="class in org.apache.hadoop.hbase.exceptions">DeserializationException</a></pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -935,7 +966,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <li class="blockList">
 <h4>parseFrom</h4>
 <pre>@InterfaceAudience.Private
-static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.387">parseFrom</a>(byte[]&nbsp;bytes,
+static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.409">parseFrom</a>(byte[]&nbsp;bytes,
                                                        int&nbsp;offset,
                                                        int&nbsp;len)
                                                 throws <a href="../../../../../org/apache/hadoop/hbase/exceptions/DeserializationException.html" title="class in org.apache.hadoop.hbase.exceptions">DeserializationException</a></pre>
@@ -957,7 +988,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>areAdjacent</h4>
-<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.410">areAdjacent</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionA,
+<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.432">areAdjacent</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionA,
                            <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionB)</pre>
 <div class="block">Check whether two regions are adjacent</div>
 <dl>
@@ -975,7 +1006,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>toByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.432">toByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</pre>
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.454">toByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>ri</code> - </dd>
@@ -992,7 +1023,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>prettyPrint</h4>
-<pre>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/client/RegionInfo.html#line.443">prettyPrint</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;encodedRegionName)</pre>
+<pre>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/client/RegionInfo.html#line.465">prettyPrint</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;encodedRegionName)</pre>
 <div class="block">Use logging.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1009,7 +1040,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.459">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.481">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                long&nbsp;regionid,
                                boolean&nbsp;newFormat)</pre>
@@ -1032,7 +1063,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.473">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.495">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                <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;id,
                                boolean&nbsp;newFormat)</pre>
@@ -1055,7 +1086,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.488">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.510">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                long&nbsp;regionid,
                                int&nbsp;replicaId,
@@ -1080,7 +1111,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.503">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.525">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                byte[]&nbsp;id,
                                boolean&nbsp;newFormat)</pre>
@@ -1103,7 +1134,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.517">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.539">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                byte[]&nbsp;id,
                                int&nbsp;replicaId,
@@ -1127,7 +1158,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>createMobRegionInfo</h4>
-<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.584">createMobRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
+<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.606">createMobRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
 <div class="block">Creates a RegionInfo object for MOB data.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1143,7 +1174,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>parseRegionName</h4>
-<pre>static&nbsp;byte[][]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.595">parseRegionName</a>(byte[]&nbsp;regionName)
+<pre>static&nbsp;byte[][]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.617">parseRegionName</a>(byte[]&nbsp;regionName)
                          throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Separate elements of a regionName.</div>
 <dl>
@@ -1162,7 +1193,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>toDelimitedByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.674">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.696">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Serializes given RegionInfo's as a byte array. Use this instead of
  <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when
@@ -1185,7 +1216,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>toDelimitedByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.698">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.720">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Use this instead of <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when writing to a stream and you want to use
  the pb mergeDelimitedFrom (w/o the delimiter, pb reads to EOF which may not be what you want).</div>
@@ -1205,7 +1236,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockList">
 <li class="blockList">
 <h4>parseFrom</h4>
-<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.710">parseFrom</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html?is-external=true" title="class or interface in java.io">DataInputStream</a>&nbsp;in)
+<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.732">parseFrom</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html?is-external=true" title="class or interface in java.io">DataInputStream</a>&nbsp;in)
                      throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Parses an RegionInfo instance from the passed in stream.
  Presumes the RegionInfo was serialized to the stream with
@@ -1226,7 +1257,7 @@ static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht
 <ul class="blockListLast">
 <li class="blockList">
 <h4>parseDelimitedFrom</h4>
-<pre>static&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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.738">parseDelimitedFrom</a>(byte[]&nbsp;bytes,
+<pre>static&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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.760">parseDelimitedFrom</a>(byte[]&nbsp;bytes,
                                            int&nbsp;offset,
                                            int&nbsp;length)
                                     throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
index 3b8cae3..db74e20 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
@@ -395,7 +395,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <!--   -->
 </a>
 <h3>Methods inherited from interface&nbsp;org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-byte:A-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-byte:A-int-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-long-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-long-int-boolean-"
 >createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-java.lang.String-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#encodeRegionName-byte:A-">encodeRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getStartKey-byte:A-">getStartKey</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getTable-byte:A-">getTable</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionI
 nfo.html#isEncodedRegionName-byte:A-">isEncodedRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseDelimitedFrom-byte:A-int-int-">parseDelimitedFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-int-int-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-java.io.DataInputStream-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFromOrNull-byte:A-">parseFromOrNull</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFromOrNull-byte:A-int-int-">parseFromOrNull</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseRegionName-byte:A-">parseRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#prettyPrint-java.lang.String-">pr
 ettyPrint</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-byte:A-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-byte:A-int-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-long-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-long-int-boolean-"
 >createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createRegionName-org.apache.hadoop.hbase.TableName-byte:A-java.lang.String-boolean-">createRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#encodeRegionName-byte:A-">encodeRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getStartKey-byte:A
 -">getStartKey</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getTable-byte:A-">getTable</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isEncodedRegionName-byte:A-">isEncodedRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseDelimitedFrom-byte:A-int-int-">parseDelimitedFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-byte:A-int-int-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom-java.io.DataInputStream-">parseFrom</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseFromOrNull-byte:A-">parseFromOrNull</a>, <a href="../../../../../org/apache/hadoop/hbas
 e/client/RegionInfo.html#parseFromOrNull-byte:A-int-int-">parseFromOrNull</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#parseRegionName-byte:A-">parseRegionName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#prettyPrint-java.lang.String-">prettyPrint</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
 </ul>
 </li>
 </ul>
@@ -712,7 +712,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedName</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/client/RegionInfoBuilder.MutableRegionInfo.html#line.303">getEncodedName</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/client/RegionInfoBuilder.MutableRegionInfo.html#line.295">getEncodedName</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getEncodedName--">getEncodedName</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -727,7 +727,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedNameAsBytes</h4>
-<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.308">getEncodedNameAsBytes</a>()</pre>
+<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.300">getEncodedNameAsBytes</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getEncodedNameAsBytes--">getEncodedNameAsBytes</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -742,7 +742,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartKey</h4>
-<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.314">getStartKey</a>()</pre>
+<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.306">getStartKey</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getStartKey--">getStartKey</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -757,7 +757,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getEndKey</h4>
-<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.321">getEndKey</a>()</pre>
+<pre>public&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.313">getEndKey</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getEndKey--">getEndKey</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -772,7 +772,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getTable</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.330">getTable</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.322">getTable</a>()</pre>
 <div class="block">Get current table name of the region</div>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
@@ -788,7 +788,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRange</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.342">containsRange</a>(byte[]&nbsp;rangeStartKey,
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.334">containsRange</a>(byte[]&nbsp;rangeStartKey,
                              byte[]&nbsp;rangeEndKey)</pre>
 <div class="block">Returns true if the given inclusive range of rows is fully contained
  by this region. For example, if the region is foo,a,g and this is
@@ -813,7 +813,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRow</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.360">containsRow</a>(byte[]&nbsp;row)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.352">containsRow</a>(byte[]&nbsp;row)</pre>
 <div class="block">Return true if the given row falls in this region.</div>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
@@ -829,7 +829,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>isMetaRegion</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.368">isMetaRegion</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.360">isMetaRegion</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isMetaRegion--">isMetaRegion</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -844,7 +844,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplit</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.376">isSplit</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.368">isSplit</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isSplit--">isSplit</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -859,7 +859,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>setSplit</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder.MutableRegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.384">setSplit</a>(boolean&nbsp;split)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder.MutableRegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.376">setSplit</a>(boolean&nbsp;split)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>split</code> - set split status</dd>
@@ -874,7 +874,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>isOffline</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.393">isOffline</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.385">isOffline</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isOffline--">isOffline</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -889,7 +889,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>setOffline</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder.MutableRegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.403">setOffline</a>(boolean&nbsp;offLine)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder.MutableRegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.395">setOffline</a>(boolean&nbsp;offLine)</pre>
 <div class="block">The parent of a region split is offline while split daughters hold
  references to the parent. Offlined regions are closed.</div>
 <dl>
@@ -906,7 +906,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplitParent</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.412">isSplitParent</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.404">isSplitParent</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#isSplitParent--">isSplitParent</a></code>&nbsp;in interface&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></code></dd>
@@ -921,7 +921,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getReplicaId</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.425">getReplicaId</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.417">getReplicaId</a>()</pre>
 <div class="block">Returns the region replica id</div>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
@@ -937,7 +937,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>toString</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.433">toString</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.425">toString</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#toString--" title="class or interface in java.lang">toString</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></code></dd>
@@ -952,7 +952,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>equals</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.449">equals</a>(<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>&nbsp;o)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.441">equals</a>(<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>&nbsp;o)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#equals-java.lang.Object-" title="class or interface in java.lang">equals</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></code></dd>
@@ -969,7 +969,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>hashCode</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.466">hashCode</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.458">hashCode</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#hashCode--" title="class or interface in java.lang">hashCode</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></code></dd>
@@ -984,7 +984,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.htm
 <ul class="blockListLast">
 <li class="blockList">
 <h4>compareTo</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.471">compareTo</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;other)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#line.463">compareTo</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;other)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true#compareTo-T-" title="class or interface in java.lang">compareTo</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;</code></dd>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/UnmodifyableHRegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/UnmodifyableHRegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/UnmodifyableHRegionInfo.html
index f810cba..30603f6 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/UnmodifyableHRegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/UnmodifyableHRegionInfo.html
@@ -218,7 +218,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/HRegionInfo.html" title=
 <!--   -->
 </a>
 <h3>Methods inherited from interface&nbsp;org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.had
 oop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo
 .html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
 </ul>
 </li>
 </ul>


[23/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ReadRequestCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432<

<TRUNCATED>

[16/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.StoreFileCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    

<TRUNCATED>

[44/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/apidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
----------------------------------------------------------------------
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html b/apidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
index 6df10fd..96d95ad 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
@@ -26,742 +26,764 @@
 <span class="sourceLineNo">018</span> */<a name="line.18"></a>
 <span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.client;<a name="line.19"></a>
 <span class="sourceLineNo">020</span><a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.DataInputStream;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import java.io.IOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.ArrayList;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.Arrays;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import java.util.Comparator;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.List;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.stream.Collectors;<a name="line.27"></a>
-<span class="sourceLineNo">028</span><a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HConstants;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.TableName;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.exceptions.DeserializationException;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.util.ByteArrayHashKey;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.util.HashKey;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.util.JenkinsHash;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.MD5Hash;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.io.DataInputBuffer;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.hadoop.util.StringUtils;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.39"></a>
-<span class="sourceLineNo">040</span><a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;<a name="line.42"></a>
-<span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>/**<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * Information about a region. A region is a range of keys in the whole keyspace<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * of a table, an identifier (a timestamp) for differentiating between subset<a name="line.46"></a>
-<span class="sourceLineNo">047</span> * ranges (after region split) and a replicaId for differentiating the instance<a name="line.47"></a>
-<span class="sourceLineNo">048</span> * for the same range and some status information about the region.<a name="line.48"></a>
-<span class="sourceLineNo">049</span> *<a name="line.49"></a>
-<span class="sourceLineNo">050</span> * The region has a unique name which consists of the following fields:<a name="line.50"></a>
-<span class="sourceLineNo">051</span> * &lt;ul&gt;<a name="line.51"></a>
-<span class="sourceLineNo">052</span> * &lt;li&gt; tableName   : The name of the table &lt;/li&gt;<a name="line.52"></a>
-<span class="sourceLineNo">053</span> * &lt;li&gt; startKey    : The startKey for the region. &lt;/li&gt;<a name="line.53"></a>
-<span class="sourceLineNo">054</span> * &lt;li&gt; regionId    : A timestamp when the region is created. &lt;/li&gt;<a name="line.54"></a>
-<span class="sourceLineNo">055</span> * &lt;li&gt; replicaId   : An id starting from 0 to differentiate replicas of the<a name="line.55"></a>
-<span class="sourceLineNo">056</span> * same region range but hosted in separated servers. The same region range can<a name="line.56"></a>
-<span class="sourceLineNo">057</span> * be hosted in multiple locations.&lt;/li&gt;<a name="line.57"></a>
-<span class="sourceLineNo">058</span> * &lt;li&gt; encodedName : An MD5 encoded string for the region name.&lt;/li&gt;<a name="line.58"></a>
-<span class="sourceLineNo">059</span> * &lt;/ul&gt;<a name="line.59"></a>
-<span class="sourceLineNo">060</span> *<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * &lt;br&gt; Other than the fields in the region name, region info contains:<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;li&gt; endKey      : the endKey for the region (exclusive) &lt;/li&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt; split       : Whether the region is split &lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt; offline     : Whether the region is offline &lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;/ul&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> *<a name="line.67"></a>
-<span class="sourceLineNo">068</span> */<a name="line.68"></a>
-<span class="sourceLineNo">069</span>@InterfaceAudience.Public<a name="line.69"></a>
-<span class="sourceLineNo">070</span>public interface RegionInfo {<a name="line.70"></a>
-<span class="sourceLineNo">071</span>  /**<a name="line.71"></a>
-<span class="sourceLineNo">072</span>   * Separator used to demarcate the encodedName in a region name<a name="line.72"></a>
-<span class="sourceLineNo">073</span>   * in the new format. See description on new format above.<a name="line.73"></a>
-<span class="sourceLineNo">074</span>   */<a name="line.74"></a>
-<span class="sourceLineNo">075</span>  @InterfaceAudience.Private<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  int ENC_SEPARATOR = '.';<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  @InterfaceAudience.Private<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  int MD5_HEX_LENGTH = 32;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  @InterfaceAudience.Private<a name="line.81"></a>
-<span class="sourceLineNo">082</span>  int DEFAULT_REPLICA_ID = 0;<a name="line.82"></a>
-<span class="sourceLineNo">083</span><a name="line.83"></a>
-<span class="sourceLineNo">084</span>  /**<a name="line.84"></a>
-<span class="sourceLineNo">085</span>   * to keep appended int's sorted in string format. Only allows 2 bytes<a name="line.85"></a>
-<span class="sourceLineNo">086</span>   * to be sorted for replicaId.<a name="line.86"></a>
-<span class="sourceLineNo">087</span>   */<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  @InterfaceAudience.Private<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  String REPLICA_ID_FORMAT = "%04X";<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>  @InterfaceAudience.Private<a name="line.91"></a>
-<span class="sourceLineNo">092</span>  byte REPLICA_ID_DELIMITER = (byte)'_';<a name="line.92"></a>
-<span class="sourceLineNo">093</span><a name="line.93"></a>
-<span class="sourceLineNo">094</span>  @InterfaceAudience.Private<a name="line.94"></a>
-<span class="sourceLineNo">095</span>  String INVALID_REGION_NAME_FORMAT_MESSAGE = "Invalid regionName format";<a name="line.95"></a>
-<span class="sourceLineNo">096</span><a name="line.96"></a>
-<span class="sourceLineNo">097</span>  @InterfaceAudience.Private<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  Comparator&lt;RegionInfo&gt; COMPARATOR<a name="line.98"></a>
-<span class="sourceLineNo">099</span>    = (RegionInfo lhs, RegionInfo rhs) -&gt; {<a name="line.99"></a>
-<span class="sourceLineNo">100</span>      if (rhs == null) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>        return 1;<a name="line.101"></a>
-<span class="sourceLineNo">102</span>      }<a name="line.102"></a>
-<span class="sourceLineNo">103</span><a name="line.103"></a>
-<span class="sourceLineNo">104</span>      // Are regions of same table?<a name="line.104"></a>
-<span class="sourceLineNo">105</span>      int result = lhs.getTable().compareTo(rhs.getTable());<a name="line.105"></a>
-<span class="sourceLineNo">106</span>      if (result != 0) {<a name="line.106"></a>
-<span class="sourceLineNo">107</span>        return result;<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      }<a name="line.108"></a>
-<span class="sourceLineNo">109</span><a name="line.109"></a>
-<span class="sourceLineNo">110</span>      // Compare start keys.<a name="line.110"></a>
-<span class="sourceLineNo">111</span>      result = Bytes.compareTo(lhs.getStartKey(), rhs.getStartKey());<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      if (result != 0) {<a name="line.112"></a>
-<span class="sourceLineNo">113</span>        return result;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      }<a name="line.114"></a>
-<span class="sourceLineNo">115</span><a name="line.115"></a>
-<span class="sourceLineNo">116</span>      // Compare end keys.<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      result = Bytes.compareTo(lhs.getEndKey(), rhs.getEndKey());<a name="line.117"></a>
-<span class="sourceLineNo">118</span><a name="line.118"></a>
-<span class="sourceLineNo">119</span>      if (result != 0) {<a name="line.119"></a>
-<span class="sourceLineNo">120</span>        if (lhs.getStartKey().length != 0<a name="line.120"></a>
-<span class="sourceLineNo">121</span>                &amp;&amp; lhs.getEndKey().length == 0) {<a name="line.121"></a>
-<span class="sourceLineNo">122</span>            return 1; // this is last region<a name="line.122"></a>
-<span class="sourceLineNo">123</span>        }<a name="line.123"></a>
-<span class="sourceLineNo">124</span>        if (rhs.getStartKey().length != 0<a name="line.124"></a>
-<span class="sourceLineNo">125</span>                &amp;&amp; rhs.getEndKey().length == 0) {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>            return -1; // o is the last region<a name="line.126"></a>
-<span class="sourceLineNo">127</span>        }<a name="line.127"></a>
-<span class="sourceLineNo">128</span>        return result;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      }<a name="line.129"></a>
-<span class="sourceLineNo">130</span><a name="line.130"></a>
-<span class="sourceLineNo">131</span>      // regionId is usually milli timestamp -- this defines older stamps<a name="line.131"></a>
-<span class="sourceLineNo">132</span>      // to be "smaller" than newer stamps in sort order.<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      if (lhs.getRegionId() &gt; rhs.getRegionId()) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>        return 1;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      } else if (lhs.getRegionId() &lt; rhs.getRegionId()) {<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        return -1;<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      }<a name="line.137"></a>
-<span class="sourceLineNo">138</span><a name="line.138"></a>
-<span class="sourceLineNo">139</span>      int replicaDiff = lhs.getReplicaId() - rhs.getReplicaId();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>      if (replicaDiff != 0) return replicaDiff;<a name="line.140"></a>
-<span class="sourceLineNo">141</span><a name="line.141"></a>
-<span class="sourceLineNo">142</span>      if (lhs.isOffline() == rhs.isOffline())<a name="line.142"></a>
-<span class="sourceLineNo">143</span>        return 0;<a name="line.143"></a>
-<span class="sourceLineNo">144</span>      if (lhs.isOffline() == true) return -1;<a name="line.144"></a>
-<span class="sourceLineNo">145</span><a name="line.145"></a>
-<span class="sourceLineNo">146</span>      return 1;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  };<a name="line.147"></a>
-<span class="sourceLineNo">148</span><a name="line.148"></a>
-<span class="sourceLineNo">149</span><a name="line.149"></a>
-<span class="sourceLineNo">150</span>  /**<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * @return Return a short, printable name for this region<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * (usually encoded name) for us logging.<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   */<a name="line.153"></a>
-<span class="sourceLineNo">154</span>  String getShortNameToLog();<a name="line.154"></a>
-<span class="sourceLineNo">155</span><a name="line.155"></a>
-<span class="sourceLineNo">156</span>  /**<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * @return the regionId.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  long getRegionId();<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  /**<a name="line.161"></a>
-<span class="sourceLineNo">162</span>   * @return the regionName as an array of bytes.<a name="line.162"></a>
-<span class="sourceLineNo">163</span>   * @see #getRegionNameAsString()<a name="line.163"></a>
-<span class="sourceLineNo">164</span>   */<a name="line.164"></a>
-<span class="sourceLineNo">165</span>  byte [] getRegionName();<a name="line.165"></a>
-<span class="sourceLineNo">166</span><a name="line.166"></a>
-<span class="sourceLineNo">167</span>  /**<a name="line.167"></a>
-<span class="sourceLineNo">168</span>   * @return Region name as a String for use in logging, etc.<a name="line.168"></a>
-<span class="sourceLineNo">169</span>   */<a name="line.169"></a>
-<span class="sourceLineNo">170</span>  String getRegionNameAsString();<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>  /**<a name="line.172"></a>
-<span class="sourceLineNo">173</span>   * @return the encoded region name.<a name="line.173"></a>
-<span class="sourceLineNo">174</span>   */<a name="line.174"></a>
-<span class="sourceLineNo">175</span>  String getEncodedName();<a name="line.175"></a>
-<span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>  /**<a name="line.177"></a>
-<span class="sourceLineNo">178</span>   * @return the encoded region name as an array of bytes.<a name="line.178"></a>
-<span class="sourceLineNo">179</span>   */<a name="line.179"></a>
-<span class="sourceLineNo">180</span>  byte [] getEncodedNameAsBytes();<a name="line.180"></a>
-<span class="sourceLineNo">181</span><a name="line.181"></a>
-<span class="sourceLineNo">182</span>  /**<a name="line.182"></a>
-<span class="sourceLineNo">183</span>   * @return the startKey.<a name="line.183"></a>
-<span class="sourceLineNo">184</span>   */<a name="line.184"></a>
-<span class="sourceLineNo">185</span>  byte [] getStartKey();<a name="line.185"></a>
-<span class="sourceLineNo">186</span><a name="line.186"></a>
-<span class="sourceLineNo">187</span>  /**<a name="line.187"></a>
-<span class="sourceLineNo">188</span>   * @return the endKey.<a name="line.188"></a>
-<span class="sourceLineNo">189</span>   */<a name="line.189"></a>
-<span class="sourceLineNo">190</span>  byte [] getEndKey();<a name="line.190"></a>
-<span class="sourceLineNo">191</span><a name="line.191"></a>
-<span class="sourceLineNo">192</span>  /**<a name="line.192"></a>
-<span class="sourceLineNo">193</span>   * @return current table name of the region<a name="line.193"></a>
-<span class="sourceLineNo">194</span>   */<a name="line.194"></a>
-<span class="sourceLineNo">195</span>  TableName getTable();<a name="line.195"></a>
-<span class="sourceLineNo">196</span><a name="line.196"></a>
-<span class="sourceLineNo">197</span>  /**<a name="line.197"></a>
-<span class="sourceLineNo">198</span>   * @return returns region replica id<a name="line.198"></a>
-<span class="sourceLineNo">199</span>   */<a name="line.199"></a>
-<span class="sourceLineNo">200</span>  int getReplicaId();<a name="line.200"></a>
-<span class="sourceLineNo">201</span><a name="line.201"></a>
-<span class="sourceLineNo">202</span>  /**<a name="line.202"></a>
-<span class="sourceLineNo">203</span>   * @return True if has been split and has daughters.<a name="line.203"></a>
-<span class="sourceLineNo">204</span>   */<a name="line.204"></a>
-<span class="sourceLineNo">205</span>  boolean isSplit();<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>  /**<a name="line.207"></a>
-<span class="sourceLineNo">208</span>   * @return True if this region is offline.<a name="line.208"></a>
-<span class="sourceLineNo">209</span>   */<a name="line.209"></a>
-<span class="sourceLineNo">210</span>  boolean isOffline();<a name="line.210"></a>
-<span class="sourceLineNo">211</span><a name="line.211"></a>
-<span class="sourceLineNo">212</span>  /**<a name="line.212"></a>
-<span class="sourceLineNo">213</span>   * @return True if this is a split parent region.<a name="line.213"></a>
-<span class="sourceLineNo">214</span>   */<a name="line.214"></a>
-<span class="sourceLineNo">215</span>  boolean isSplitParent();<a name="line.215"></a>
-<span class="sourceLineNo">216</span><a name="line.216"></a>
-<span class="sourceLineNo">217</span>  /**<a name="line.217"></a>
-<span class="sourceLineNo">218</span>   * @return true if this region is a meta region.<a name="line.218"></a>
-<span class="sourceLineNo">219</span>   */<a name="line.219"></a>
-<span class="sourceLineNo">220</span>  boolean isMetaRegion();<a name="line.220"></a>
-<span class="sourceLineNo">221</span><a name="line.221"></a>
-<span class="sourceLineNo">222</span>  /**<a name="line.222"></a>
-<span class="sourceLineNo">223</span>   * @param rangeStartKey<a name="line.223"></a>
-<span class="sourceLineNo">224</span>   * @param rangeEndKey<a name="line.224"></a>
-<span class="sourceLineNo">225</span>   * @return true if the given inclusive range of rows is fully contained<a name="line.225"></a>
-<span class="sourceLineNo">226</span>   * by this region. For example, if the region is foo,a,g and this is<a name="line.226"></a>
-<span class="sourceLineNo">227</span>   * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.227"></a>
-<span class="sourceLineNo">228</span>   * ["b","z"] it will return false.<a name="line.228"></a>
-<span class="sourceLineNo">229</span>   * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.229"></a>
-<span class="sourceLineNo">230</span>   */<a name="line.230"></a>
-<span class="sourceLineNo">231</span>  boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey);<a name="line.231"></a>
-<span class="sourceLineNo">232</span><a name="line.232"></a>
-<span class="sourceLineNo">233</span>  /**<a name="line.233"></a>
-<span class="sourceLineNo">234</span>   * @param row<a name="line.234"></a>
-<span class="sourceLineNo">235</span>   * @return true if the given row falls in this region.<a name="line.235"></a>
-<span class="sourceLineNo">236</span>   */<a name="line.236"></a>
-<span class="sourceLineNo">237</span>  boolean containsRow(byte[] row);<a name="line.237"></a>
-<span class="sourceLineNo">238</span><a name="line.238"></a>
-<span class="sourceLineNo">239</span>  /**<a name="line.239"></a>
-<span class="sourceLineNo">240</span>   * Does region name contain its encoded name?<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * @param regionName region name<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * @return boolean indicating if this a new format region<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   *         name which contains its encoded name.<a name="line.243"></a>
-<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
-<span class="sourceLineNo">245</span>  @InterfaceAudience.Private<a name="line.245"></a>
-<span class="sourceLineNo">246</span>  static boolean hasEncodedName(final byte[] regionName) {<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    // check if region name ends in ENC_SEPARATOR<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    return (regionName.length &gt;= 1) &amp;&amp;<a name="line.248"></a>
-<span class="sourceLineNo">249</span>      (regionName[regionName.length - 1] == RegionInfo.ENC_SEPARATOR);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>  }<a name="line.250"></a>
-<span class="sourceLineNo">251</span><a name="line.251"></a>
-<span class="sourceLineNo">252</span>  /**<a name="line.252"></a>
-<span class="sourceLineNo">253</span>   * @return the encodedName<a name="line.253"></a>
-<span class="sourceLineNo">254</span>   */<a name="line.254"></a>
-<span class="sourceLineNo">255</span>  @InterfaceAudience.Private<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  static String encodeRegionName(final byte [] regionName) {<a name="line.256"></a>
-<span class="sourceLineNo">257</span>    String encodedName;<a name="line.257"></a>
-<span class="sourceLineNo">258</span>    if (hasEncodedName(regionName)) {<a name="line.258"></a>
-<span class="sourceLineNo">259</span>      // region is in new format:<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      // &lt;tableName&gt;,&lt;startKey&gt;,&lt;regionIdTimeStamp&gt;/encodedName/<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      encodedName = Bytes.toString(regionName,<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      regionName.length - MD5_HEX_LENGTH - 1,<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      MD5_HEX_LENGTH);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>    } else {<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      // old format region name. First hbase:meta region also<a name="line.265"></a>
-<span class="sourceLineNo">266</span>      // use this format.EncodedName is the JenkinsHash value.<a name="line.266"></a>
-<span class="sourceLineNo">267</span>      HashKey&lt;byte[]&gt; key = new ByteArrayHashKey(regionName, 0, regionName.length);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>      int hashVal = Math.abs(JenkinsHash.getInstance().hash(key, 0));<a name="line.268"></a>
-<span class="sourceLineNo">269</span>      encodedName = String.valueOf(hashVal);<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    return encodedName;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>  /**<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * (usually encoded name) for us logging.<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   */<a name="line.277"></a>
-<span class="sourceLineNo">278</span>  static String getShortNameToLog(RegionInfo...hris) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>    return getShortNameToLog(Arrays.asList(hris));<a name="line.279"></a>
-<span class="sourceLineNo">280</span>  }<a name="line.280"></a>
-<span class="sourceLineNo">281</span><a name="line.281"></a>
-<span class="sourceLineNo">282</span>  /**<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * (usually encoded name) for us logging.<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   */<a name="line.285"></a>
-<span class="sourceLineNo">286</span>  static String getShortNameToLog(final List&lt;RegionInfo&gt; ris) {<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    return ris.stream().map(ri -&gt; ri.getShortNameToLog()).<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    collect(Collectors.toList()).toString();<a name="line.288"></a>
-<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
-<span class="sourceLineNo">290</span><a name="line.290"></a>
-<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Gets the table name from the specified region name.<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * @param regionName to extract the table name from<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   * @return Table name<a name="line.294"></a>
-<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
-<span class="sourceLineNo">296</span>  @InterfaceAudience.Private<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  // This method should never be used. Its awful doing parse from bytes.<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // It is fallback in case we can't get the tablename any other way. Could try removing it.<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  // Keeping it Audience Private so can remove at later date.<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  static TableName getTable(final byte [] regionName) {<a name="line.300"></a>
-<span class="sourceLineNo">301</span>    int offset = -1;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    for (int i = 0; i &lt; regionName.length; i++) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      if (regionName[i] == HConstants.DELIMITER) {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>        offset = i;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        break;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    }<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    if (offset &lt;= 0) {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>      throw new IllegalArgumentException("offset=" + offset);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    byte[] buff  = new byte[offset];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    System.arraycopy(regionName, 0, buff, 0, offset);<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return TableName.valueOf(buff);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  /**<a name="line.316"></a>
-<span class="sourceLineNo">317</span>   * Gets the start key from the specified region name.<a name="line.317"></a>
-<span class="sourceLineNo">318</span>   * @param regionName<a name="line.318"></a>
-<span class="sourceLineNo">319</span>   * @return Start key.<a name="line.319"></a>
-<span class="sourceLineNo">320</span>   * @throws java.io.IOException<a name="line.320"></a>
-<span class="sourceLineNo">321</span>   */<a name="line.321"></a>
-<span class="sourceLineNo">322</span>  static byte[] getStartKey(final byte[] regionName) throws IOException {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    return parseRegionName(regionName)[1];<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>  @InterfaceAudience.Private<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  static boolean isEncodedRegionName(byte[] regionName) throws IOException {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    try {<a name="line.328"></a>
-<span class="sourceLineNo">329</span>      parseRegionName(regionName);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      return false;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    } catch (IOException e) {<a name="line.331"></a>
-<span class="sourceLineNo">332</span>      if (StringUtils.stringifyException(e)<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      .contains(INVALID_REGION_NAME_FORMAT_MESSAGE)) {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>        return true;<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      }<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      throw e;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    }<a name="line.337"></a>
-<span class="sourceLineNo">338</span>  }<a name="line.338"></a>
-<span class="sourceLineNo">339</span><a name="line.339"></a>
-<span class="sourceLineNo">340</span>  /**<a name="line.340"></a>
-<span class="sourceLineNo">341</span>   * @param bytes<a name="line.341"></a>
-<span class="sourceLineNo">342</span>   * @return A deserialized {@link RegionInfo}<a name="line.342"></a>
-<span class="sourceLineNo">343</span>   * or null if we failed deserialize or passed bytes null<a name="line.343"></a>
-<span class="sourceLineNo">344</span>   */<a name="line.344"></a>
-<span class="sourceLineNo">345</span>  @InterfaceAudience.Private<a name="line.345"></a>
-<span class="sourceLineNo">346</span>  static RegionInfo parseFromOrNull(final byte [] bytes) {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    if (bytes == null) return null;<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    return parseFromOrNull(bytes, 0, bytes.length);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>  }<a name="line.349"></a>
-<span class="sourceLineNo">350</span><a name="line.350"></a>
-<span class="sourceLineNo">351</span>  /**<a name="line.351"></a>
-<span class="sourceLineNo">352</span>   * @param bytes<a name="line.352"></a>
-<span class="sourceLineNo">353</span>   * @param offset<a name="line.353"></a>
-<span class="sourceLineNo">354</span>   * @param len<a name="line.354"></a>
-<span class="sourceLineNo">355</span>   * @return A deserialized {@link RegionInfo} or null<a name="line.355"></a>
-<span class="sourceLineNo">356</span>   *  if we failed deserialize or passed bytes null<a name="line.356"></a>
-<span class="sourceLineNo">357</span>   */<a name="line.357"></a>
-<span class="sourceLineNo">358</span>  @InterfaceAudience.Private<a name="line.358"></a>
-<span class="sourceLineNo">359</span>  static RegionInfo parseFromOrNull(final byte [] bytes, int offset, int len) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    if (bytes == null || len &lt;= 0) return null;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    try {<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      return parseFrom(bytes, offset, len);<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    } catch (DeserializationException e) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      return null;<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><a name="line.367"></a>
-<span class="sourceLineNo">368</span>  /**<a name="line.368"></a>
-<span class="sourceLineNo">369</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.369"></a>
-<span class="sourceLineNo">370</span>   * @return A deserialized {@link RegionInfo}<a name="line.370"></a>
-<span class="sourceLineNo">371</span>   * @throws DeserializationException<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   */<a name="line.372"></a>
-<span class="sourceLineNo">373</span>  @InterfaceAudience.Private<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  static RegionInfo parseFrom(final byte [] bytes) throws DeserializationException {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>    if (bytes == null) return null;<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    return parseFrom(bytes, 0, bytes.length);<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  }<a name="line.377"></a>
-<span class="sourceLineNo">378</span><a name="line.378"></a>
-<span class="sourceLineNo">379</span>  /**<a name="line.379"></a>
-<span class="sourceLineNo">380</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.380"></a>
-<span class="sourceLineNo">381</span>   * @param offset starting point in the byte array<a name="line.381"></a>
-<span class="sourceLineNo">382</span>   * @param len length to read on the byte array<a name="line.382"></a>
-<span class="sourceLineNo">383</span>   * @return A deserialized {@link RegionInfo}<a name="line.383"></a>
-<span class="sourceLineNo">384</span>   * @throws DeserializationException<a name="line.384"></a>
-<span class="sourceLineNo">385</span>   */<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  @InterfaceAudience.Private<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  static RegionInfo parseFrom(final byte [] bytes, int offset, int len)<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  throws DeserializationException {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      int pblen = ProtobufUtil.lengthOfPBMagic();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      try {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder();<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        HBaseProtos.RegionInfo ri = builder.build();<a name="line.394"></a>
-<span class="sourceLineNo">395</span>        return ProtobufUtil.toRegionInfo(ri);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      } catch (IOException e) {<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        throw new DeserializationException(e);<a name="line.397"></a>
-<span class="sourceLineNo">398</span>      }<a name="line.398"></a>
-<span class="sourceLineNo">399</span>    } else {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      throw new DeserializationException("PB encoded RegionInfo expected");<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><a name="line.403"></a>
-<span class="sourceLineNo">404</span>  /**<a name="line.404"></a>
-<span class="sourceLineNo">405</span>   * Check whether two regions are adjacent<a name="line.405"></a>
-<span class="sourceLineNo">406</span>   * @param regionA<a name="line.406"></a>
-<span class="sourceLineNo">407</span>   * @param regionB<a name="line.407"></a>
-<span class="sourceLineNo">408</span>   * @return true if two regions are adjacent<a name="line.408"></a>
-<span class="sourceLineNo">409</span>   */<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  static boolean areAdjacent(RegionInfo regionA, RegionInfo regionB) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    if (regionA == null || regionB == null) {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      throw new IllegalArgumentException(<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      "Can't check whether adjacent for null region");<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    }<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    RegionInfo a = regionA;<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    RegionInfo b = regionB;<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    if (Bytes.compareTo(a.getStartKey(), b.getStartKey()) &gt; 0) {<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      a = regionB;<a name="line.418"></a>
-<span class="sourceLineNo">419</span>      b = regionA;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    if (Bytes.compareTo(a.getEndKey(), b.getStartKey()) == 0) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      return true;<a name="line.422"></a>
+<span class="sourceLineNo">021</span>import edu.umd.cs.findbugs.annotations.CheckForNull;<a name="line.21"></a>
+<span class="sourceLineNo">022</span><a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.io.DataInputStream;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import java.io.IOException;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import java.util.ArrayList;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import java.util.Arrays;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.Comparator;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.List;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.stream.Collectors;<a name="line.29"></a>
+<span class="sourceLineNo">030</span><a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HConstants;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.TableName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.exceptions.DeserializationException;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.util.ByteArrayHashKey;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.HashKey;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.JenkinsHash;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.util.MD5Hash;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.hadoop.io.DataInputBuffer;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.apache.hadoop.util.StringUtils;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.41"></a>
+<span class="sourceLineNo">042</span><a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;<a name="line.44"></a>
+<span class="sourceLineNo">045</span><a name="line.45"></a>
+<span class="sourceLineNo">046</span>/**<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * Information about a region. A region is a range of keys in the whole keyspace<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * of a table, an identifier (a timestamp) for differentiating between subset<a name="line.48"></a>
+<span class="sourceLineNo">049</span> * ranges (after region split) and a replicaId for differentiating the instance<a name="line.49"></a>
+<span class="sourceLineNo">050</span> * for the same range and some status information about the region.<a name="line.50"></a>
+<span class="sourceLineNo">051</span> *<a name="line.51"></a>
+<span class="sourceLineNo">052</span> * The region has a unique name which consists of the following fields:<a name="line.52"></a>
+<span class="sourceLineNo">053</span> * &lt;ul&gt;<a name="line.53"></a>
+<span class="sourceLineNo">054</span> * &lt;li&gt; tableName   : The name of the table &lt;/li&gt;<a name="line.54"></a>
+<span class="sourceLineNo">055</span> * &lt;li&gt; startKey    : The startKey for the region. &lt;/li&gt;<a name="line.55"></a>
+<span class="sourceLineNo">056</span> * &lt;li&gt; regionId    : A timestamp when the region is created. &lt;/li&gt;<a name="line.56"></a>
+<span class="sourceLineNo">057</span> * &lt;li&gt; replicaId   : An id starting from 0 to differentiate replicas of the<a name="line.57"></a>
+<span class="sourceLineNo">058</span> * same region range but hosted in separated servers. The same region range can<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * be hosted in multiple locations.&lt;/li&gt;<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * &lt;li&gt; encodedName : An MD5 encoded string for the region name.&lt;/li&gt;<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * &lt;/ul&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> *<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;br&gt; Other than the fields in the region name, region info contains:<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;ul&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt; endKey      : the endKey for the region (exclusive) &lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt; split       : Whether the region is split &lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt; offline     : Whether the region is offline &lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
+<span class="sourceLineNo">070</span> */<a name="line.70"></a>
+<span class="sourceLineNo">071</span>@InterfaceAudience.Public<a name="line.71"></a>
+<span class="sourceLineNo">072</span>public interface RegionInfo {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>  /**<a name="line.73"></a>
+<span class="sourceLineNo">074</span>   * Separator used to demarcate the encodedName in a region name<a name="line.74"></a>
+<span class="sourceLineNo">075</span>   * in the new format. See description on new format above.<a name="line.75"></a>
+<span class="sourceLineNo">076</span>   */<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  @InterfaceAudience.Private<a name="line.77"></a>
+<span class="sourceLineNo">078</span>  int ENC_SEPARATOR = '.';<a name="line.78"></a>
+<span class="sourceLineNo">079</span><a name="line.79"></a>
+<span class="sourceLineNo">080</span>  @InterfaceAudience.Private<a name="line.80"></a>
+<span class="sourceLineNo">081</span>  int MD5_HEX_LENGTH = 32;<a name="line.81"></a>
+<span class="sourceLineNo">082</span><a name="line.82"></a>
+<span class="sourceLineNo">083</span>  @InterfaceAudience.Private<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  int DEFAULT_REPLICA_ID = 0;<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  /**<a name="line.86"></a>
+<span class="sourceLineNo">087</span>   * to keep appended int's sorted in string format. Only allows 2 bytes<a name="line.87"></a>
+<span class="sourceLineNo">088</span>   * to be sorted for replicaId.<a name="line.88"></a>
+<span class="sourceLineNo">089</span>   */<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  @InterfaceAudience.Private<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  String REPLICA_ID_FORMAT = "%04X";<a name="line.91"></a>
+<span class="sourceLineNo">092</span><a name="line.92"></a>
+<span class="sourceLineNo">093</span>  @InterfaceAudience.Private<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  byte REPLICA_ID_DELIMITER = (byte)'_';<a name="line.94"></a>
+<span class="sourceLineNo">095</span><a name="line.95"></a>
+<span class="sourceLineNo">096</span>  @InterfaceAudience.Private<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  String INVALID_REGION_NAME_FORMAT_MESSAGE = "Invalid regionName format";<a name="line.97"></a>
+<span class="sourceLineNo">098</span><a name="line.98"></a>
+<span class="sourceLineNo">099</span>  @InterfaceAudience.Private<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  Comparator&lt;RegionInfo&gt; COMPARATOR<a name="line.100"></a>
+<span class="sourceLineNo">101</span>    = (RegionInfo lhs, RegionInfo rhs) -&gt; {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      if (rhs == null) {<a name="line.102"></a>
+<span class="sourceLineNo">103</span>        return 1;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>      }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>      // Are regions of same table?<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      int result = lhs.getTable().compareTo(rhs.getTable());<a name="line.107"></a>
+<span class="sourceLineNo">108</span>      if (result != 0) {<a name="line.108"></a>
+<span class="sourceLineNo">109</span>        return result;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>      }<a name="line.110"></a>
+<span class="sourceLineNo">111</span><a name="line.111"></a>
+<span class="sourceLineNo">112</span>      // Compare start keys.<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      result = Bytes.compareTo(lhs.getStartKey(), rhs.getStartKey());<a name="line.113"></a>
+<span class="sourceLineNo">114</span>      if (result != 0) {<a name="line.114"></a>
+<span class="sourceLineNo">115</span>        return result;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>      }<a name="line.116"></a>
+<span class="sourceLineNo">117</span><a name="line.117"></a>
+<span class="sourceLineNo">118</span>      // Compare end keys.<a name="line.118"></a>
+<span class="sourceLineNo">119</span>      result = Bytes.compareTo(lhs.getEndKey(), rhs.getEndKey());<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>      if (result != 0) {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>        if (lhs.getStartKey().length != 0<a name="line.122"></a>
+<span class="sourceLineNo">123</span>                &amp;&amp; lhs.getEndKey().length == 0) {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>            return 1; // this is last region<a name="line.124"></a>
+<span class="sourceLineNo">125</span>        }<a name="line.125"></a>
+<span class="sourceLineNo">126</span>        if (rhs.getStartKey().length != 0<a name="line.126"></a>
+<span class="sourceLineNo">127</span>                &amp;&amp; rhs.getEndKey().length == 0) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>            return -1; // o is the last region<a name="line.128"></a>
+<span class="sourceLineNo">129</span>        }<a name="line.129"></a>
+<span class="sourceLineNo">130</span>        return result;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>      }<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>      // regionId is usually milli timestamp -- this defines older stamps<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      // to be "smaller" than newer stamps in sort order.<a name="line.134"></a>
+<span class="sourceLineNo">135</span>      if (lhs.getRegionId() &gt; rhs.getRegionId()) {<a name="line.135"></a>
+<span class="sourceLineNo">136</span>        return 1;<a name="line.136"></a>
+<span class="sourceLineNo">137</span>      } else if (lhs.getRegionId() &lt; rhs.getRegionId()) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>        return -1;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      }<a name="line.139"></a>
+<span class="sourceLineNo">140</span><a name="line.140"></a>
+<span class="sourceLineNo">141</span>      int replicaDiff = lhs.getReplicaId() - rhs.getReplicaId();<a name="line.141"></a>
+<span class="sourceLineNo">142</span>      if (replicaDiff != 0) return replicaDiff;<a name="line.142"></a>
+<span class="sourceLineNo">143</span><a name="line.143"></a>
+<span class="sourceLineNo">144</span>      if (lhs.isOffline() == rhs.isOffline())<a name="line.144"></a>
+<span class="sourceLineNo">145</span>        return 0;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>      if (lhs.isOffline() == true) return -1;<a name="line.146"></a>
+<span class="sourceLineNo">147</span><a name="line.147"></a>
+<span class="sourceLineNo">148</span>      return 1;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  };<a name="line.149"></a>
+<span class="sourceLineNo">150</span><a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * @return Return a short, printable name for this region<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * (usually encoded name) for us logging.<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  String getShortNameToLog();<a name="line.156"></a>
+<span class="sourceLineNo">157</span><a name="line.157"></a>
+<span class="sourceLineNo">158</span>  /**<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   * @return the regionId.<a name="line.159"></a>
+<span class="sourceLineNo">160</span>   */<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  long getRegionId();<a name="line.161"></a>
+<span class="sourceLineNo">162</span><a name="line.162"></a>
+<span class="sourceLineNo">163</span>  /**<a name="line.163"></a>
+<span class="sourceLineNo">164</span>   * @return the regionName as an array of bytes.<a name="line.164"></a>
+<span class="sourceLineNo">165</span>   * @see #getRegionNameAsString()<a name="line.165"></a>
+<span class="sourceLineNo">166</span>   */<a name="line.166"></a>
+<span class="sourceLineNo">167</span>  byte [] getRegionName();<a name="line.167"></a>
+<span class="sourceLineNo">168</span><a name="line.168"></a>
+<span class="sourceLineNo">169</span>  /**<a name="line.169"></a>
+<span class="sourceLineNo">170</span>   * @return Region name as a String for use in logging, etc.<a name="line.170"></a>
+<span class="sourceLineNo">171</span>   */<a name="line.171"></a>
+<span class="sourceLineNo">172</span>  String getRegionNameAsString();<a name="line.172"></a>
+<span class="sourceLineNo">173</span><a name="line.173"></a>
+<span class="sourceLineNo">174</span>  /**<a name="line.174"></a>
+<span class="sourceLineNo">175</span>   * @return the encoded region name.<a name="line.175"></a>
+<span class="sourceLineNo">176</span>   */<a name="line.176"></a>
+<span class="sourceLineNo">177</span>  String getEncodedName();<a name="line.177"></a>
+<span class="sourceLineNo">178</span><a name="line.178"></a>
+<span class="sourceLineNo">179</span>  /**<a name="line.179"></a>
+<span class="sourceLineNo">180</span>   * @return the encoded region name as an array of bytes.<a name="line.180"></a>
+<span class="sourceLineNo">181</span>   */<a name="line.181"></a>
+<span class="sourceLineNo">182</span>  byte [] getEncodedNameAsBytes();<a name="line.182"></a>
+<span class="sourceLineNo">183</span><a name="line.183"></a>
+<span class="sourceLineNo">184</span>  /**<a name="line.184"></a>
+<span class="sourceLineNo">185</span>   * @return the startKey.<a name="line.185"></a>
+<span class="sourceLineNo">186</span>   */<a name="line.186"></a>
+<span class="sourceLineNo">187</span>  byte [] getStartKey();<a name="line.187"></a>
+<span class="sourceLineNo">188</span><a name="line.188"></a>
+<span class="sourceLineNo">189</span>  /**<a name="line.189"></a>
+<span class="sourceLineNo">190</span>   * @return the endKey.<a name="line.190"></a>
+<span class="sourceLineNo">191</span>   */<a name="line.191"></a>
+<span class="sourceLineNo">192</span>  byte [] getEndKey();<a name="line.192"></a>
+<span class="sourceLineNo">193</span><a name="line.193"></a>
+<span class="sourceLineNo">194</span>  /**<a name="line.194"></a>
+<span class="sourceLineNo">195</span>   * @return current table name of the region<a name="line.195"></a>
+<span class="sourceLineNo">196</span>   */<a name="line.196"></a>
+<span class="sourceLineNo">197</span>  TableName getTable();<a name="line.197"></a>
+<span class="sourceLineNo">198</span><a name="line.198"></a>
+<span class="sourceLineNo">199</span>  /**<a name="line.199"></a>
+<span class="sourceLineNo">200</span>   * @return returns region replica id<a name="line.200"></a>
+<span class="sourceLineNo">201</span>   */<a name="line.201"></a>
+<span class="sourceLineNo">202</span>  int getReplicaId();<a name="line.202"></a>
+<span class="sourceLineNo">203</span><a name="line.203"></a>
+<span class="sourceLineNo">204</span>  /**<a name="line.204"></a>
+<span class="sourceLineNo">205</span>   * @return True if has been split and has daughters.<a name="line.205"></a>
+<span class="sourceLineNo">206</span>   */<a name="line.206"></a>
+<span class="sourceLineNo">207</span>  boolean isSplit();<a name="line.207"></a>
+<span class="sourceLineNo">208</span><a name="line.208"></a>
+<span class="sourceLineNo">209</span>  /**<a name="line.209"></a>
+<span class="sourceLineNo">210</span>   * @return True if this region is offline.<a name="line.210"></a>
+<span class="sourceLineNo">211</span>   */<a name="line.211"></a>
+<span class="sourceLineNo">212</span>  boolean isOffline();<a name="line.212"></a>
+<span class="sourceLineNo">213</span><a name="line.213"></a>
+<span class="sourceLineNo">214</span>  /**<a name="line.214"></a>
+<span class="sourceLineNo">215</span>   * @return True if this is a split parent region.<a name="line.215"></a>
+<span class="sourceLineNo">216</span>   */<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  boolean isSplitParent();<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  /**<a name="line.219"></a>
+<span class="sourceLineNo">220</span>   * @return true if this region is a meta region.<a name="line.220"></a>
+<span class="sourceLineNo">221</span>   */<a name="line.221"></a>
+<span class="sourceLineNo">222</span>  boolean isMetaRegion();<a name="line.222"></a>
+<span class="sourceLineNo">223</span><a name="line.223"></a>
+<span class="sourceLineNo">224</span>  /**<a name="line.224"></a>
+<span class="sourceLineNo">225</span>   * @param rangeStartKey<a name="line.225"></a>
+<span class="sourceLineNo">226</span>   * @param rangeEndKey<a name="line.226"></a>
+<span class="sourceLineNo">227</span>   * @return true if the given inclusive range of rows is fully contained<a name="line.227"></a>
+<span class="sourceLineNo">228</span>   * by this region. For example, if the region is foo,a,g and this is<a name="line.228"></a>
+<span class="sourceLineNo">229</span>   * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.229"></a>
+<span class="sourceLineNo">230</span>   * ["b","z"] it will return false.<a name="line.230"></a>
+<span class="sourceLineNo">231</span>   * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.231"></a>
+<span class="sourceLineNo">232</span>   */<a name="line.232"></a>
+<span class="sourceLineNo">233</span>  boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey);<a name="line.233"></a>
+<span class="sourceLineNo">234</span><a name="line.234"></a>
+<span class="sourceLineNo">235</span>  /**<a name="line.235"></a>
+<span class="sourceLineNo">236</span>   * @param row<a name="line.236"></a>
+<span class="sourceLineNo">237</span>   * @return true if the given row falls in this region.<a name="line.237"></a>
+<span class="sourceLineNo">238</span>   */<a name="line.238"></a>
+<span class="sourceLineNo">239</span>  boolean containsRow(byte[] row);<a name="line.239"></a>
+<span class="sourceLineNo">240</span><a name="line.240"></a>
+<span class="sourceLineNo">241</span>  /**<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Does region name contain its encoded name?<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * @param regionName region name<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   * @return boolean indicating if this a new format region<a name="line.244"></a>
+<span class="sourceLineNo">245</span>   *         name which contains its encoded name.<a name="line.245"></a>
+<span class="sourceLineNo">246</span>   */<a name="line.246"></a>
+<span class="sourceLineNo">247</span>  @InterfaceAudience.Private<a name="line.247"></a>
+<span class="sourceLineNo">248</span>  static boolean hasEncodedName(final byte[] regionName) {<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    // check if region name ends in ENC_SEPARATOR<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    return (regionName.length &gt;= 1) &amp;&amp;<a name="line.250"></a>
+<span class="sourceLineNo">251</span>      (regionName[regionName.length - 1] == RegionInfo.ENC_SEPARATOR);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>  }<a name="line.252"></a>
+<span class="sourceLineNo">253</span><a name="line.253"></a>
+<span class="sourceLineNo">254</span>  /**<a name="line.254"></a>
+<span class="sourceLineNo">255</span>   * @return the encodedName<a name="line.255"></a>
+<span class="sourceLineNo">256</span>   */<a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @InterfaceAudience.Private<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  static String encodeRegionName(final byte [] regionName) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    String encodedName;<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    if (hasEncodedName(regionName)) {<a name="line.260"></a>
+<span class="sourceLineNo">261</span>      // region is in new format:<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      // &lt;tableName&gt;,&lt;startKey&gt;,&lt;regionIdTimeStamp&gt;/encodedName/<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      encodedName = Bytes.toString(regionName,<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      regionName.length - MD5_HEX_LENGTH - 1,<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      MD5_HEX_LENGTH);<a name="line.265"></a>
+<span class="sourceLineNo">266</span>    } else {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      // old format region name. First hbase:meta region also<a name="line.267"></a>
+<span class="sourceLineNo">268</span>      // use this format.EncodedName is the JenkinsHash value.<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      HashKey&lt;byte[]&gt; key = new ByteArrayHashKey(regionName, 0, regionName.length);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>      int hashVal = Math.abs(JenkinsHash.getInstance().hash(key, 0));<a name="line.270"></a>
+<span class="sourceLineNo">271</span>      encodedName = String.valueOf(hashVal);<a name="line.271"></a>
+<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
+<span class="sourceLineNo">273</span>    return encodedName;<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  }<a name="line.274"></a>
+<span class="sourceLineNo">275</span><a name="line.275"></a>
+<span class="sourceLineNo">276</span>  @InterfaceAudience.Private<a name="line.276"></a>
+<span class="sourceLineNo">277</span>  static String getRegionNameAsString(byte[] regionName) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>    return getRegionNameAsString(null, regionName);<a name="line.278"></a>
+<span class="sourceLineNo">279</span>  }<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  @InterfaceAudience.Private<a name="line.281"></a>
+<span class="sourceLineNo">282</span>  static String getRegionNameAsString(@CheckForNull RegionInfo ri, byte[] regionName) {<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    if (RegionInfo.hasEncodedName(regionName)) {<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      // new format region names already have their encoded name.<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return Bytes.toStringBinary(regionName);<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    // old format. regionNameStr doesn't have the region name.<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    if (ri == null) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>      return Bytes.toStringBinary(regionName) + "." + RegionInfo.encodeRegionName(regionName);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>    } else {<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      return Bytes.toStringBinary(regionName) + "." + ri.getEncodedName();<a name="line.292"></a>
+<span class="sourceLineNo">293</span>    }<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
+<span class="sourceLineNo">295</span><a name="line.295"></a>
+<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
+<span class="sourceLineNo">297</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>   * (usually encoded name) for us logging.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>   */<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  static String getShortNameToLog(RegionInfo...hris) {<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    return getShortNameToLog(Arrays.asList(hris));<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  }<a name="line.302"></a>
+<span class="sourceLineNo">303</span><a name="line.303"></a>
+<span class="sourceLineNo">304</span>  /**<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.305"></a>
+<span class="sourceLineNo">306</span>   * (usually encoded name) for us logging.<a name="line.306"></a>
+<span class="sourceLineNo">307</span>   */<a name="line.307"></a>
+<span class="sourceLineNo">308</span>  static String getShortNameToLog(final List&lt;RegionInfo&gt; ris) {<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    return ris.stream().map(ri -&gt; ri.getShortNameToLog()).<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    collect(Collectors.toList()).toString();<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  }<a name="line.311"></a>
+<span class="sourceLineNo">312</span><a name="line.312"></a>
+<span class="sourceLineNo">313</span>  /**<a name="line.313"></a>
+<span class="sourceLineNo">314</span>   * Gets the table name from the specified region name.<a name="line.314"></a>
+<span class="sourceLineNo">315</span>   * @param regionName to extract the table name from<a name="line.315"></a>
+<span class="sourceLineNo">316</span>   * @return Table name<a name="line.316"></a>
+<span class="sourceLineNo">317</span>   */<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  @InterfaceAudience.Private<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // This method should never be used. Its awful doing parse from bytes.<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // It is fallback in case we can't get the tablename any other way. Could try removing it.<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // Keeping it Audience Private so can remove at later date.<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  static TableName getTable(final byte [] regionName) {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    int offset = -1;<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    for (int i = 0; i &lt; regionName.length; i++) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      if (regionName[i] == HConstants.DELIMITER) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>        offset = i;<a name="line.326"></a>
+<span class="sourceLineNo">327</span>        break;<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    }<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    if (offset &lt;= 0) {<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      throw new IllegalArgumentException("offset=" + offset);<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    }<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    byte[] buff  = new byte[offset];<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    System.arraycopy(regionName, 0, buff, 0, offset);<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    return TableName.valueOf(buff);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>  }<a name="line.336"></a>
+<span class="sourceLineNo">337</span><a name="line.337"></a>
+<span class="sourceLineNo">338</span>  /**<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * Gets the start key from the specified region name.<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @param regionName<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   * @return Start key.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>   * @throws java.io.IOException<a name="line.342"></a>
+<span class="sourceLineNo">343</span>   */<a name="line.343"></a>
+<span class="sourceLineNo">344</span>  static byte[] getStartKey(final byte[] regionName) throws IOException {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    return parseRegionName(regionName)[1];<a name="line.345"></a>
+<span class="sourceLineNo">346</span>  }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>  @InterfaceAudience.Private<a name="line.348"></a>
+<span class="sourceLineNo">349</span>  static boolean isEncodedRegionName(byte[] regionName) throws IOException {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    try {<a name="line.350"></a>
+<span class="sourceLineNo">351</span>      parseRegionName(regionName);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      return false;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    } catch (IOException e) {<a name="line.353"></a>
+<span class="sourceLineNo">354</span>      if (StringUtils.stringifyException(e)<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      .contains(INVALID_REGION_NAME_FORMAT_MESSAGE)) {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        return true;<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      }<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      throw e;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    }<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>  /**<a name="line.362"></a>
+<span class="sourceLineNo">363</span>   * @param bytes<a name="line.363"></a>
+<span class="sourceLineNo">364</span>   * @return A deserialized {@link RegionInfo}<a name="line.364"></a>
+<span class="sourceLineNo">365</span>   * or null if we failed deserialize or passed bytes null<a name="line.365"></a>
+<span class="sourceLineNo">366</span>   */<a name="line.366"></a>
+<span class="sourceLineNo">367</span>  @InterfaceAudience.Private<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  static RegionInfo parseFromOrNull(final byte [] bytes) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    if (bytes == null) return null;<a name="line.369"></a>
+<span class="sourceLineNo">370</span>    return parseFromOrNull(bytes, 0, bytes.length);<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>   * @param bytes<a name="line.374"></a>
+<span class="sourceLineNo">375</span>   * @param offset<a name="line.375"></a>
+<span class="sourceLineNo">376</span>   * @param len<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * @return A deserialized {@link RegionInfo} or null<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   *  if we failed deserialize or passed bytes null<a name="line.378"></a>
+<span class="sourceLineNo">379</span>   */<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  @InterfaceAudience.Private<a name="line.380"></a>
+<span class="sourceLineNo">381</span>  static RegionInfo parseFromOrNull(final byte [] bytes, int offset, int len) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    if (bytes == null || len &lt;= 0) return null;<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    try {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      return parseFrom(bytes, offset, len);<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    } catch (DeserializationException e) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      return null;<a name="line.386"></a>
+<span class="sourceLineNo">387</span>    }<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  }<a name="line.388"></a>
+<span class="sourceLineNo">389</span><a name="line.389"></a>
+<span class="sourceLineNo">390</span>  /**<a name="line.390"></a>
+<span class="sourceLineNo">391</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.391"></a>
+<span class="sourceLineNo">392</span>   * @return A deserialized {@link RegionInfo}<a name="line.392"></a>
+<span class="sourceLineNo">393</span>   * @throws DeserializationException<a name="line.393"></a>
+<span class="sourceLineNo">394</span>   */<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  @InterfaceAudience.Private<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  static RegionInfo parseFrom(final byte [] bytes) throws DeserializationException {<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    if (bytes == null) return null;<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    return parseFrom(bytes, 0, bytes.length);<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  }<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>  /**<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * @param offset starting point in the byte array<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * @param len length to read on the byte array<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   * @return A deserialized {@link RegionInfo}<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * @throws DeserializationException<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   */<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  @InterfaceAudience.Private<a name="line.408"></a>
+<span class="sourceLineNo">409</span>  static RegionInfo parseFrom(final byte [] bytes, int offset, int len)<a name="line.409"></a>
+<span class="sourceLineNo">410</span>  throws DeserializationException {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      int pblen = ProtobufUtil.lengthOfPBMagic();<a name="line.412"></a>
+<span class="sourceLineNo">413</span>      try {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder();<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen);<a name="line.415"></a>
+<span class="sourceLineNo">416</span>        HBaseProtos.RegionInfo ri = builder.build();<a name="line.416"></a>
+<span class="sourceLineNo">417</span>        return ProtobufUtil.toRegionInfo(ri);<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      } catch (IOException e) {<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        throw new DeserializationException(e);<a name="line.419"></a>
+<span class="sourceLineNo">420</span>      }<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    } else {<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      throw new DeserializationException("PB encoded RegionInfo expected");<a name="line.422"></a>
 <span class="sourceLineNo">423</span>    }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>    return false;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>  }<a name="line.425"></a>
-<span class="sourceLineNo">426</span><a name="line.426"></a>
-<span class="sourceLineNo">427</span>  /**<a name="line.427"></a>
-<span class="sourceLineNo">428</span>   * @param ri<a name="line.428"></a>
-<span class="sourceLineNo">429</span>   * @return This instance serialized as protobuf w/ a magic pb prefix.<a name="line.429"></a>
-<span class="sourceLineNo">430</span>   * @see #parseFrom(byte[])<a name="line.430"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  /**<a name="line.426"></a>
+<span class="sourceLineNo">427</span>   * Check whether two regions are adjacent<a name="line.427"></a>
+<span class="sourceLineNo">428</span>   * @param regionA<a name="line.428"></a>
+<span class="sourceLineNo">429</span>   * @param regionB<a name="line.429"></a>
+<span class="sourceLineNo">430</span>   * @return true if two regions are adjacent<a name="line.430"></a>
 <span class="sourceLineNo">431</span>   */<a name="line.431"></a>
-<span class="sourceLineNo">432</span>  static byte [] toByteArray(RegionInfo ri) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    byte [] bytes = ProtobufUtil.toRegionInfo(ri).toByteArray();<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    return ProtobufUtil.prependPBMagic(bytes);<a name="line.434"></a>
-<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
-<span class="sourceLineNo">436</span><a name="line.436"></a>
-<span class="sourceLineNo">437</span>  /**<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * Use logging.<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   * @param encodedRegionName The encoded regionname.<a name="line.439"></a>
-<span class="sourceLineNo">440</span>   * @return &lt;code&gt;hbase:meta&lt;/code&gt; if passed &lt;code&gt;1028785192&lt;/code&gt; else returns<a name="line.440"></a>
-<span class="sourceLineNo">441</span>   * &lt;code&gt;encodedRegionName&lt;/code&gt;<a name="line.441"></a>
-<span class="sourceLineNo">442</span>   */<a name="line.442"></a>
-<span class="sourceLineNo">443</span>  static String prettyPrint(final String encodedRegionName) {<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (encodedRegionName.equals("1028785192")) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      return encodedRegionName + "/hbase:meta";<a name="line.445"></a>
-<span class="sourceLineNo">446</span>    }<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    return encodedRegionName;<a name="line.447"></a>
-<span class="sourceLineNo">448</span>  }<a name="line.448"></a>
-<span class="sourceLineNo">449</span><a name="line.449"></a>
-<span class="sourceLineNo">450</span>  /**<a name="line.450"></a>
-<span class="sourceLineNo">451</span>   * Make a region name of passed parameters.<a name="line.451"></a>
-<span class="sourceLineNo">452</span>   * @param tableName<a name="line.452"></a>
-<span class="sourceLineNo">453</span>   * @param startKey Can be null<a name="line.453"></a>
-<span class="sourceLineNo">454</span>   * @param regionid Region id (Usually timestamp from when region was created).<a name="line.454"></a>
-<span class="sourceLineNo">455</span>   * @param newFormat should we create the region name in the new format<a name="line.455"></a>
-<span class="sourceLineNo">456</span>   *                  (such that it contains its encoded name?).<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * @return Region name made of passed tableName, startKey and id<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   */<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  static byte [] createRegionName(final TableName tableName, final byte[] startKey,<a name="line.459"></a>
-<span class="sourceLineNo">460</span>                                  final long regionid, boolean newFormat) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    return createRegionName(tableName, startKey, Long.toString(regionid), newFormat);<a name="line.461"></a>
-<span class="sourceLineNo">462</span>  }<a name="line.462"></a>
-<span class="sourceLineNo">463</span><a name="line.463"></a>
-<span class="sourceLineNo">464</span>  /**<a name="line.464"></a>
-<span class="sourceLineNo">465</span>   * Make a region name of passed parameters.<a name="line.465"></a>
-<span class="sourceLineNo">466</span>   * @param tableName<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * @param startKey Can be null<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @param newFormat should we create the region name in the new format<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   *                  (such that it contains its encoded name?).<a name="line.470"></a>
-<span class="sourceLineNo">471</span>   * @return Region name made of passed tableName, startKey and id<a name="line.471"></a>
-<span class="sourceLineNo">472</span>   */<a name="line.472"></a>
-<span class="sourceLineNo">473</span>  static byte [] createRegionName(final TableName tableName,<a name="line.473"></a>
-<span class="sourceLineNo">474</span>                                  final byte[] startKey, final String id, boolean newFormat) {<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    return createRegionName(tableName, startKey, Bytes.toBytes(id), newFormat);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  }<a name="line.476"></a>
-<span class="sourceLineNo">477</span><a name="line.477"></a>
-<span class="sourceLineNo">478</span>  /**<a name="line.478"></a>
-<span class="sourceLineNo">479</span>   * Make a region name of passed parameters.<a name="line.479"></a>
-<span class="sourceLineNo">480</span>   * @param tableName<a name="line.480"></a>
-<span class="sourceLineNo">481</span>   * @param startKey Can be null<a name="line.481"></a>
-<span class="sourceLineNo">482</span>   * @param regionid Region id (Usually timestamp from when region was created).<a name="line.482"></a>
-<span class="sourceLineNo">483</span>   * @param replicaId<a name="line.483"></a>
-<span class="sourceLineNo">484</span>   * @param newFormat should we create the region name in the new format<a name="line.484"></a>
-<span class="sourceLineNo">485</span>   *                  (such that it contains its encoded name?).<a name="line.485"></a>
-<span class="sourceLineNo">486</span>   * @return Region name made of passed tableName, startKey, id and replicaId<a name="line.486"></a>
-<span class="sourceLineNo">487</span>   */<a name="line.487"></a>
-<span class="sourceLineNo">488</span>  static byte [] createRegionName(final TableName tableName,<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      final byte[] startKey, final long regionid, int replicaId, boolean newFormat) {<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    return createRegionName(tableName, startKey, Bytes.toBytes(Long.toString(regionid)),<a name="line.490"></a>
-<span class="sourceLineNo">491</span>      replicaId, newFormat);<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  /**<a name="line.494"></a>
-<span class="sourceLineNo">495</span>   * Make a region name of passed parameters.<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * @param tableName<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * @param startKey Can be null<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param newFormat should we create the region name in the new format<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   *                  (such that it contains its encoded name?).<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   * @return Region name made of passed tableName, startKey and id<a name="line.501"></a>
-<span class="sourceLineNo">502</span>   */<a name="line.502"></a>
-<span class="sourceLineNo">503</span>  static byte [] createRegionName(final TableName tableName,<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      final byte[] startKey, final byte[] id, boolean newFormat) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    return createRegionName(tableName, startKey, id, DEFAULT_REPLICA_ID, newFormat);<a name="line.505"></a>
-<span class="sourceLineNo">506</span>  }<a name="line.506"></a>
-<span class="sourceLineNo">507</span><a name="line.507"></a>
-<span class="sourceLineNo">508</span>  /**<a name="line.508"></a>
-<span class="sourceLineNo">509</span>   * Make a region name of passed parameters.<a name="line.509"></a>
-<span class="sourceLineNo">510</span>   * @param tableName<a name="line.510"></a>
-<span class="sourceLineNo">511</span>   * @param startKey Can be null<a name="line.511"></a>
-<span class="sourceLineNo">512</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.512"></a>
-<span class="sourceLineNo">513</span>   * @param replicaId<a name="line.513"></a>
-<span class="sourceLineNo">514</span>   * @param newFormat should we create the region name in the new format<a name="line.514"></a>
-<span class="sourceLineNo">515</span>   * @return Region name made of passed tableName, startKey, id and replicaId<a name="line.515"></a>
-<span class="sourceLineNo">516</span>   */<a name="line.516"></a>
-<span class="sourceLineNo">517</span>  static byte [] createRegionName(final TableName tableName,<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      final byte[] startKey, final byte[] id, final int replicaId, boolean newFormat) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    int len = tableName.getName().length + 2 + id.length + (startKey == null? 0: startKey.length);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>    if (newFormat) {<a name="line.520"></a>
-<span class="sourceLineNo">521</span>      len += MD5_HEX_LENGTH + 2;<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    }<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    byte[] replicaIdBytes = null;<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    // Special casing: replicaId is only appended if replicaId is greater than<a name="line.524"></a>
-<span class="sourceLineNo">525</span>    // 0. This is because all regions in meta would have to be migrated to the new<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    // name otherwise<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    if (replicaId &gt; 0) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>      // use string representation for replica id<a name="line.528"></a>
-<span class="sourceLineNo">529</span>      replicaIdBytes = Bytes.toBytes(String.format(REPLICA_ID_FORMAT, replicaId));<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      len += 1 + replicaIdBytes.length;<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    byte [] b = new byte [len];<a name="line.533"></a>
-<span class="sourceLineNo">534</span><a name="line.534"></a>
-<span class="sourceLineNo">535</span>    int offset = tableName.getName().length;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    System.arraycopy(tableName.getName(), 0, b, 0, offset);<a name="line.536"></a>
-<span class="sourceLineNo">537</span>    b[offset++] = HConstants.DELIMITER;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    if (startKey != null &amp;&amp; startKey.length &gt; 0) {<a name="line.538"></a>
-<span class="sourceLineNo">539</span>      System.arraycopy(startKey, 0, b, offset, startKey.length);<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      offset += startKey.length;<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    }<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    b[offset++] = HConstants.DELIMITER;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>    System.arraycopy(id, 0, b, offset, id.length);<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    offset += id.length;<a name="line.544"></a>
-<span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (replicaIdBytes != null) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      b[offset++] = REPLICA_ID_DELIMITER;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      System.arraycopy(replicaIdBytes, 0, b, offset, replicaIdBytes.length);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>      offset += replicaIdBytes.length;<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    }<a name="line.550"></a>
-<span class="sourceLineNo">551</span><a name="line.551"></a>
-<span class="sourceLineNo">552</span>    if (newFormat) {<a name="line.552"></a>
-<span class="sourceLineNo">553</span>      //<a name="line.553"></a>
-<span class="sourceLineNo">554</span>      // Encoded name should be built into the region name.<a name="line.554"></a>
-<span class="sourceLineNo">555</span>      //<a name="line.555"></a>
-<span class="sourceLineNo">556</span>      // Use the region name thus far (namely, &lt;tablename&gt;,&lt;startKey&gt;,&lt;id&gt;_&lt;replicaId&gt;)<a name="line.556"></a>
-<span class="sourceLineNo">557</span>      // to compute a MD5 hash to be used as the encoded name, and append<a name="line.557"></a>
-<span class="sourceLineNo">558</span>      // it to the byte buffer.<a name="line.558"></a>
-<span class="sourceLineNo">559</span>      //<a name="line.559"></a>
-<span class="sourceLineNo">560</span>      String md5Hash = MD5Hash.getMD5AsHex(b, 0, offset);<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      byte [] md5HashBytes = Bytes.toBytes(md5Hash);<a name="line.561"></a>
-<span class="sourceLineNo">562</span><a name="line.562"></a>
-<span class="sourceLineNo">563</span>      if (md5HashBytes.length != MD5_HEX_LENGTH) {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>        System.out.println("MD5-hash length mismatch: Expected=" + MD5_HEX_LENGTH +<a name="line.564"></a>
-<span class="sourceLineNo">565</span>        "; Got=" + md5HashBytes.length);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      }<a name="line.566"></a>
+<span class="sourceLineNo">432</span>  static boolean areAdjacent(RegionInf

<TRUNCATED>

[46/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/apache_hbase_reference_guide.pdf
----------------------------------------------------------------------
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index f399d9f..deb2ad9 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,16 +5,16 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 1.5.0.alpha.15, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20181108143309+00'00')
-/CreationDate (D:20181108144803+00'00')
+/ModDate (D:20181109143344+00'00')
+/CreationDate (D:20181109144916+00'00')
 >>
 endobj
 2 0 obj
 << /Type /Catalog
 /Pages 3 0 R
 /Names 28 0 R
-/Outlines 5015 0 R
-/PageLabels 5265 0 R
+/Outlines 5028 0 R
+/PageLabels 5278 0 R
 /PageMode /UseOutlines
 /OpenAction [7 0 R /FitH 842.89]
 /ViewerPreferences << /DisplayDocTitle true
@@ -23,8 +23,8 @@ endobj
 endobj
 3 0 obj
 << /Type /Pages
-/Count 787
-/Kids [7 0 R 12 0 R 14 0 R 16 0 R 18 0 R 20 0 R 22 0 R 24 0 R 26 0 R 46 0 R 49 0 R 52 0 R 56 0 R 63 0 R 65 0 R 69 0 R 71 0 R 73 0 R 80 0 R 83 0 R 85 0 R 91 0 R 94 0 R 96 0 R 98 0 R 105 0 R 112 0 R 117 0 R 119 0 R 135 0 R 140 0 R 148 0 R 157 0 R 165 0 R 169 0 R 178 0 R 189 0 R 193 0 R 195 0 R 199 0 R 208 0 R 217 0 R 225 0 R 234 0 R 239 0 R 248 0 R 256 0 R 265 0 R 278 0 R 285 0 R 295 0 R 303 0 R 311 0 R 318 0 R 327 0 R 333 0 R 339 0 R 346 0 R 354 0 R 362 0 R 373 0 R 386 0 R 394 0 R 401 0 R 409 0 R 417 0 R 426 0 R 436 0 R 444 0 R 451 0 R 458 0 R 467 0 R 480 0 R 488 0 R 495 0 R 503 0 R 511 0 R 520 0 R 525 0 R 531 0 R 536 0 R 540 0 R 556 0 R 567 0 R 571 0 R 586 0 R 591 0 R 596 0 R 598 0 R 600 0 R 603 0 R 605 0 R 607 0 R 615 0 R 621 0 R 624 0 R 628 0 R 637 0 R 648 0 R 656 0 R 660 0 R 664 0 R 666 0 R 679 0 R 693 0 R 700 0 R 712 0 R 722 0 R 733 0 R 745 0 R 763 0 R 780 0 R 787 0 R 794 0 R 800 0 R 803 0 R 807 0 R 811 0 R 814 0 R 817 0 R 819 0 R 822 0 R 826 0 R 828 0 R 832 0 R 838 0 R 843 0 R 
 847 0 R 850 0 R 856 0 R 858 0 R 862 0 R 870 0 R 872 0 R 875 0 R 878 0 R 881 0 R 884 0 R 898 0 R 906 0 R 917 0 R 928 0 R 934 0 R 944 0 R 955 0 R 958 0 R 962 0 R 965 0 R 970 0 R 979 0 R 987 0 R 992 0 R 996 0 R 1001 0 R 1005 0 R 1007 0 R 1022 0 R 1033 0 R 1038 0 R 1045 0 R 1048 0 R 1056 0 R 1064 0 R 1069 0 R 1074 0 R 1079 0 R 1081 0 R 1083 0 R 1085 0 R 1095 0 R 1103 0 R 1107 0 R 1114 0 R 1121 0 R 1129 0 R 1133 0 R 1139 0 R 1144 0 R 1152 0 R 1156 0 R 1161 0 R 1163 0 R 1169 0 R 1177 0 R 1183 0 R 1190 0 R 1201 0 R 1205 0 R 1207 0 R 1209 0 R 1213 0 R 1216 0 R 1221 0 R 1224 0 R 1236 0 R 1240 0 R 1246 0 R 1254 0 R 1259 0 R 1263 0 R 1267 0 R 1269 0 R 1272 0 R 1275 0 R 1278 0 R 1282 0 R 1286 0 R 1290 0 R 1295 0 R 1299 0 R 1302 0 R 1304 0 R 1314 0 R 1316 0 R 1321 0 R 1334 0 R 1338 0 R 1344 0 R 1346 0 R 1357 0 R 1360 0 R 1366 0 R 1374 0 R 1377 0 R 1384 0 R 1391 0 R 1394 0 R 1396 0 R 1405 0 R 1407 0 R 1409 0 R 1412 0 R 1414 0 R 1416 0 R 1418 0 R 1420 0 R 1423 0 R 1427 0 R 1432 0 R 1434 0 R 1436 0
  R 1438 0 R 1443 0 R 1450 0 R 1456 0 R 1459 0 R 1461 0 R 1464 0 R 1468 0 R 1472 0 R 1475 0 R 1477 0 R 1479 0 R 1482 0 R 1487 0 R 1493 0 R 1501 0 R 1515 0 R 1529 0 R 1532 0 R 1537 0 R 1550 0 R 1555 0 R 1570 0 R 1578 0 R 1582 0 R 1591 0 R 1606 0 R 1618 0 R 1621 0 R 1635 0 R 1643 0 R 1648 0 R 1659 0 R 1664 0 R 1670 0 R 1676 0 R 1688 0 R 1691 0 R 1700 0 R 1703 0 R 1712 0 R 1717 0 R 1722 0 R 1726 0 R 1739 0 R 1741 0 R 1747 0 R 1753 0 R 1756 0 R 1764 0 R 1772 0 R 1776 0 R 1778 0 R 1780 0 R 1792 0 R 1798 0 R 1807 0 R 1814 0 R 1827 0 R 1833 0 R 1839 0 R 1850 0 R 1856 0 R 1861 0 R 1865 0 R 1869 0 R 1872 0 R 1877 0 R 1882 0 R 1888 0 R 1893 0 R 1897 0 R 1906 0 R 1912 0 R 1915 0 R 1919 0 R 1928 0 R 1935 0 R 1941 0 R 1948 0 R 1952 0 R 1955 0 R 1960 0 R 1965 0 R 1971 0 R 1973 0 R 1975 0 R 1978 0 R 1989 0 R 1992 0 R 1999 0 R 2007 0 R 2012 0 R 2015 0 R 2020 0 R 2022 0 R 2025 0 R 2030 0 R 2033 0 R 2035 0 R 2038 0 R 2043 0 R 2046 0 R 2056 0 R 2061 0 R 2066 0 R 2068 0 R 2076 0 R 2083 0 R 2090 0 R 2096
  0 R 2101 0 R 2103 0 R 2112 0 R 2122 0 R 2132 0 R 2138 0 R 2145 0 R 2147 0 R 2152 0 R 2154 0 R 2156 0 R 2160 0 R 2163 0 R 2166 0 R 2171 0 R 2175 0 R 2186 0 R 2189 0 R 2192 0 R 2196 0 R 2200 0 R 2203 0 R 2205 0 R 2210 0 R 2213 0 R 2215 0 R 2220 0 R 2230 0 R 2232 0 R 2234 0 R 2236 0 R 2238 0 R 2241 0 R 2243 0 R 2245 0 R 2248 0 R 2250 0 R 2252 0 R 2256 0 R 2261 0 R 2270 0 R 2272 0 R 2274 0 R 2280 0 R 2282 0 R 2287 0 R 2289 0 R 2291 0 R 2298 0 R 2303 0 R 2307 0 R 2312 0 R 2316 0 R 2318 0 R 2320 0 R 2324 0 R 2327 0 R 2329 0 R 2331 0 R 2335 0 R 2337 0 R 2340 0 R 2342 0 R 2344 0 R 2346 0 R 2353 0 R 2356 0 R 2361 0 R 2363 0 R 2365 0 R 2367 0 R 2369 0 R 2377 0 R 2388 0 R 2402 0 R 2413 0 R 2417 0 R 2422 0 R 2426 0 R 2429 0 R 2434 0 R 2440 0 R 2442 0 R 2445 0 R 2447 0 R 2449 0 R 2451 0 R 2456 0 R 2458 0 R 2471 0 R 2474 0 R 2482 0 R 2488 0 R 2500 0 R 2514 0 R 2527 0 R 2546 0 R 2548 0 R 2550 0 R 2554 0 R 2572 0 R 2578 0 R 2590 0 R 2594 0 R 2598 0 R 2607 0 R 2619 0 R 2624 0 R 2634 0 R 2647 0 R 26
 66 0 R 2675 0 R 2678 0 R 2687 0 R 2704 0 R 2711 0 R 2714 0 R 2719 0 R 2723 0 R 2726 0 R 2735 0 R 2744 0 R 2747 0 R 2749 0 R 2753 0 R 2767 0 R 2776 0 R 2781 0 R 2786 0 R 2789 0 R 2791 0 R 2793 0 R 2795 0 R 2797 0 R 2802 0 R 2815 0 R 2825 0 R 2833 0 R 2840 0 R 2845 0 R 2855 0 R 2862 0 R 2869 0 R 2871 0 R 2880 0 R 2888 0 R 2890 0 R 2894 0 R 2896 0 R 2907 0 R 2913 0 R 2915 0 R 2924 0 R 2927 0 R 2937 0 R 2941 0 R 2949 0 R 2957 0 R 2962 0 R 2966 0 R 2970 0 R 2972 0 R 2978 0 R 2982 0 R 2986 0 R 2992 0 R 2998 0 R 3001 0 R 3007 0 R 3011 0 R 3020 0 R 3025 0 R 3031 0 R 3041 0 R 3048 0 R 3055 0 R 3058 0 R 3061 0 R 3067 0 R 3073 0 R 3076 0 R 3081 0 R 3093 0 R 3101 0 R 3106 0 R 3108 0 R 3114 0 R 3117 0 R 3119 0 R 3123 0 R 3128 0 R 3133 0 R 3140 0 R 3147 0 R 3154 0 R 3162 0 R 3168 0 R 3173 0 R 3177 0 R 3180 0 R 3183 0 R 3192 0 R 3197 0 R 3201 0 R 3209 0 R 3214 0 R 3217 0 R 3228 0 R 3233 0 R 3236 0 R 3238 0 R 3240 0 R 3250 0 R 3257 0 R 3261 0 R 3264 0 R 3271 0 R 3275 0 R 3278 0 R 3282 0 R 3287 0 R 
 3295 0 R 3300 0 R 3305 0 R 3310 0 R 3312 0 R 3315 0 R 3317 0 R 3321 0 R 3332 0 R 3334 0 R 3338 0 R 3341 0 R 3345 0 R 3348 0 R 3352 0 R 3354 0 R 3367 0 R 3372 0 R 3377 0 R 3383 0 R 3391 0 R 3393 0 R 3401 0 R 3419 0 R 3431 0 R 3439 0 R 3453 0 R 3456 0 R 3461 0 R 3463 0 R 3470 0 R 3473 0 R 3478 0 R 3481 0 R 3483 0 R 3485 0 R 3487 0 R 3491 0 R 3509 0 R 3512 0 R 3517 0 R 3523 0 R 3533 0 R 3538 0 R 3548 0 R 3559 0 R 3566 0 R 3571 0 R 3578 0 R 3583 0 R 3586 0 R 3594 0 R 3598 0 R 3603 0 R 3608 0 R 3621 0 R 3624 0 R 3630 0 R 3636 0 R 3641 0 R 3651 0 R 3660 0 R 3666 0 R 3675 0 R 3684 0 R 3689 0 R 3695 0 R 3701 0 R 3706 0 R 3708 0 R 3714 0 R 3721 0 R 3723 0 R 3731 0 R 3733 0 R 3739 0 R 3747 0 R 3753 0 R 3762 0 R 3768 0 R 3779 0 R 3788 0 R 3800 0 R 3810 0 R 3821 0 R 3825 0 R 3827 0 R 3831 0 R 3845 0 R 3851 0 R 3855 0 R 3861 0 R 3865 0 R 3868 0 R 3873 0 R 3875 0 R 3879 0 R 3881 0 R 3885 0 R 3888 0 R 3891 0 R 3899 0 R 3901 0 R 3907 0 R 3910 0 R 3916 0 R 3920 0 R 3923 0 R 3926 0 R 3929 0 R 3933 0 
 R 3936 0 R 3941 0 R 3946 0 R 3949 0 R 3957 0 R 3961 0 R 3965 0 R 3967 0 R 3970 0 R 3973 0 R 3978 0 R 3985 0 R 3991 0 R 3995 0 R 3998 0 R 4005 0 R 4013 0 R 4017 0 R 4020 0 R 4022 0 R 4026 0 R 4031 0 R 4036 0 R 4039 0 R 4048 0 R 4053 0 R 4057 0 R 4060 0 R 4068 0 R 4073 0 R 4081 0 R 4086 0 R 4088 0 R 4094 0 R 4096 0 R 4101 0 R 4105 0 R 4110 0 R 4114 0 R 4126 0 R 4142 0 R 4157 0 R 4162 0 R 4164 0 R 4166 0 R 4168 0 R 4170 0 R 4172 0 R 4181 0 R 4185 0 R 4189 0 R 4193 0 R 4195 0 R 4202 0 R 4212 0 R 4219 0 R 4222 0 R 4225 0 R 4227 0 R 4234 0 R 4241 0 R 4251 0 R 4255 0 R 4258 0 R 4262 0 R 4265 0 R 4271 0 R 4274 0 R 4289 0 R 4294 0 R 4317 0 R 4321 0 R 4328 0 R 4339 0 R 4348 0 R 4351 0 R 4354 0 R 4357 0 R 4373 0 R 4378 0 R 4385 0 R 4388 0 R 4391 0 R 4398 0 R 4403 0 R 4407 0 R 4409 0 R 4415 0 R 4422 0 R 4430 0 R 4434 0 R 4439 0 R 4444 0 R 4449 0 R 4456 0 R 4463 0 R 4470 0 R 4478 0 R 4486 0 R 4490 0 R 4499 0 R 4508 0 R 4514 0 R]
+/Count 789
+/Kids [7 0 R 12 0 R 14 0 R 16 0 R 18 0 R 20 0 R 22 0 R 24 0 R 26 0 R 46 0 R 49 0 R 52 0 R 56 0 R 63 0 R 65 0 R 69 0 R 71 0 R 73 0 R 80 0 R 83 0 R 85 0 R 91 0 R 94 0 R 96 0 R 98 0 R 105 0 R 112 0 R 117 0 R 119 0 R 135 0 R 140 0 R 148 0 R 157 0 R 165 0 R 169 0 R 178 0 R 189 0 R 193 0 R 195 0 R 199 0 R 208 0 R 217 0 R 225 0 R 234 0 R 239 0 R 248 0 R 256 0 R 265 0 R 278 0 R 285 0 R 295 0 R 303 0 R 311 0 R 318 0 R 327 0 R 333 0 R 339 0 R 346 0 R 354 0 R 362 0 R 373 0 R 386 0 R 394 0 R 401 0 R 409 0 R 417 0 R 426 0 R 436 0 R 444 0 R 451 0 R 458 0 R 467 0 R 480 0 R 488 0 R 495 0 R 503 0 R 511 0 R 520 0 R 525 0 R 531 0 R 536 0 R 540 0 R 556 0 R 567 0 R 571 0 R 586 0 R 591 0 R 596 0 R 598 0 R 600 0 R 603 0 R 605 0 R 607 0 R 615 0 R 621 0 R 624 0 R 628 0 R 637 0 R 648 0 R 656 0 R 660 0 R 664 0 R 666 0 R 679 0 R 693 0 R 700 0 R 712 0 R 722 0 R 733 0 R 745 0 R 763 0 R 780 0 R 787 0 R 794 0 R 800 0 R 803 0 R 807 0 R 811 0 R 814 0 R 817 0 R 819 0 R 822 0 R 826 0 R 828 0 R 832 0 R 838 0 R 843 0 R 
 847 0 R 850 0 R 856 0 R 858 0 R 862 0 R 870 0 R 872 0 R 875 0 R 878 0 R 881 0 R 884 0 R 898 0 R 906 0 R 917 0 R 928 0 R 934 0 R 944 0 R 955 0 R 958 0 R 962 0 R 965 0 R 970 0 R 979 0 R 987 0 R 992 0 R 996 0 R 1001 0 R 1005 0 R 1007 0 R 1022 0 R 1033 0 R 1038 0 R 1045 0 R 1048 0 R 1056 0 R 1064 0 R 1069 0 R 1074 0 R 1079 0 R 1081 0 R 1083 0 R 1085 0 R 1095 0 R 1103 0 R 1107 0 R 1114 0 R 1121 0 R 1129 0 R 1133 0 R 1139 0 R 1144 0 R 1152 0 R 1156 0 R 1161 0 R 1163 0 R 1169 0 R 1177 0 R 1183 0 R 1190 0 R 1201 0 R 1205 0 R 1207 0 R 1209 0 R 1213 0 R 1216 0 R 1221 0 R 1224 0 R 1236 0 R 1240 0 R 1246 0 R 1254 0 R 1259 0 R 1263 0 R 1267 0 R 1269 0 R 1272 0 R 1275 0 R 1278 0 R 1282 0 R 1286 0 R 1290 0 R 1295 0 R 1299 0 R 1302 0 R 1304 0 R 1314 0 R 1316 0 R 1321 0 R 1334 0 R 1338 0 R 1344 0 R 1346 0 R 1357 0 R 1360 0 R 1366 0 R 1374 0 R 1377 0 R 1384 0 R 1391 0 R 1394 0 R 1396 0 R 1405 0 R 1407 0 R 1409 0 R 1412 0 R 1414 0 R 1416 0 R 1418 0 R 1420 0 R 1423 0 R 1427 0 R 1432 0 R 1434 0 R 1436 0
  R 1438 0 R 1443 0 R 1450 0 R 1456 0 R 1459 0 R 1461 0 R 1464 0 R 1468 0 R 1472 0 R 1475 0 R 1477 0 R 1479 0 R 1482 0 R 1487 0 R 1493 0 R 1501 0 R 1515 0 R 1529 0 R 1532 0 R 1537 0 R 1550 0 R 1555 0 R 1570 0 R 1578 0 R 1582 0 R 1591 0 R 1606 0 R 1618 0 R 1621 0 R 1635 0 R 1643 0 R 1648 0 R 1659 0 R 1664 0 R 1670 0 R 1676 0 R 1688 0 R 1691 0 R 1700 0 R 1703 0 R 1712 0 R 1717 0 R 1722 0 R 1726 0 R 1739 0 R 1741 0 R 1747 0 R 1753 0 R 1756 0 R 1764 0 R 1772 0 R 1776 0 R 1778 0 R 1780 0 R 1792 0 R 1798 0 R 1807 0 R 1814 0 R 1827 0 R 1833 0 R 1839 0 R 1850 0 R 1856 0 R 1861 0 R 1865 0 R 1869 0 R 1872 0 R 1877 0 R 1882 0 R 1888 0 R 1893 0 R 1897 0 R 1906 0 R 1912 0 R 1915 0 R 1919 0 R 1928 0 R 1935 0 R 1941 0 R 1948 0 R 1952 0 R 1955 0 R 1960 0 R 1965 0 R 1971 0 R 1973 0 R 1975 0 R 1978 0 R 1989 0 R 1992 0 R 1999 0 R 2007 0 R 2012 0 R 2015 0 R 2020 0 R 2022 0 R 2025 0 R 2030 0 R 2033 0 R 2035 0 R 2038 0 R 2043 0 R 2046 0 R 2056 0 R 2061 0 R 2066 0 R 2068 0 R 2076 0 R 2083 0 R 2090 0 R 2096
  0 R 2101 0 R 2103 0 R 2112 0 R 2122 0 R 2132 0 R 2138 0 R 2145 0 R 2147 0 R 2152 0 R 2154 0 R 2156 0 R 2160 0 R 2163 0 R 2166 0 R 2171 0 R 2175 0 R 2186 0 R 2189 0 R 2192 0 R 2196 0 R 2200 0 R 2203 0 R 2205 0 R 2210 0 R 2213 0 R 2215 0 R 2220 0 R 2230 0 R 2232 0 R 2234 0 R 2236 0 R 2238 0 R 2241 0 R 2243 0 R 2245 0 R 2248 0 R 2250 0 R 2252 0 R 2256 0 R 2261 0 R 2270 0 R 2272 0 R 2274 0 R 2280 0 R 2282 0 R 2287 0 R 2289 0 R 2291 0 R 2298 0 R 2303 0 R 2307 0 R 2312 0 R 2316 0 R 2318 0 R 2320 0 R 2324 0 R 2327 0 R 2329 0 R 2331 0 R 2335 0 R 2337 0 R 2340 0 R 2342 0 R 2344 0 R 2346 0 R 2353 0 R 2356 0 R 2361 0 R 2363 0 R 2365 0 R 2367 0 R 2369 0 R 2377 0 R 2388 0 R 2402 0 R 2413 0 R 2417 0 R 2422 0 R 2426 0 R 2429 0 R 2434 0 R 2440 0 R 2442 0 R 2445 0 R 2447 0 R 2449 0 R 2451 0 R 2456 0 R 2458 0 R 2471 0 R 2474 0 R 2482 0 R 2488 0 R 2500 0 R 2514 0 R 2527 0 R 2546 0 R 2548 0 R 2550 0 R 2554 0 R 2572 0 R 2578 0 R 2590 0 R 2594 0 R 2598 0 R 2607 0 R 2619 0 R 2624 0 R 2634 0 R 2647 0 R 26
 66 0 R 2675 0 R 2678 0 R 2687 0 R 2704 0 R 2711 0 R 2714 0 R 2719 0 R 2723 0 R 2726 0 R 2735 0 R 2744 0 R 2747 0 R 2749 0 R 2753 0 R 2767 0 R 2776 0 R 2781 0 R 2786 0 R 2789 0 R 2791 0 R 2793 0 R 2795 0 R 2797 0 R 2802 0 R 2815 0 R 2825 0 R 2833 0 R 2840 0 R 2845 0 R 2855 0 R 2862 0 R 2869 0 R 2871 0 R 2880 0 R 2888 0 R 2890 0 R 2894 0 R 2896 0 R 2907 0 R 2913 0 R 2915 0 R 2924 0 R 2927 0 R 2937 0 R 2941 0 R 2949 0 R 2957 0 R 2962 0 R 2966 0 R 2970 0 R 2972 0 R 2978 0 R 2982 0 R 2986 0 R 2992 0 R 2998 0 R 3001 0 R 3007 0 R 3011 0 R 3020 0 R 3025 0 R 3031 0 R 3041 0 R 3048 0 R 3055 0 R 3058 0 R 3061 0 R 3067 0 R 3073 0 R 3076 0 R 3081 0 R 3093 0 R 3101 0 R 3106 0 R 3108 0 R 3114 0 R 3117 0 R 3119 0 R 3123 0 R 3128 0 R 3133 0 R 3140 0 R 3147 0 R 3154 0 R 3162 0 R 3168 0 R 3173 0 R 3177 0 R 3180 0 R 3183 0 R 3192 0 R 3197 0 R 3201 0 R 3209 0 R 3214 0 R 3217 0 R 3228 0 R 3233 0 R 3236 0 R 3238 0 R 3240 0 R 3250 0 R 3257 0 R 3261 0 R 3265 0 R 3273 0 R 3277 0 R 3284 0 R 3288 0 R 3291 0 R 
 3295 0 R 3300 0 R 3308 0 R 3313 0 R 3318 0 R 3323 0 R 3325 0 R 3328 0 R 3330 0 R 3334 0 R 3345 0 R 3347 0 R 3351 0 R 3354 0 R 3358 0 R 3361 0 R 3365 0 R 3367 0 R 3380 0 R 3385 0 R 3390 0 R 3396 0 R 3404 0 R 3406 0 R 3415 0 R 3433 0 R 3445 0 R 3453 0 R 3467 0 R 3470 0 R 3475 0 R 3477 0 R 3484 0 R 3487 0 R 3492 0 R 3495 0 R 3497 0 R 3499 0 R 3501 0 R 3505 0 R 3522 0 R 3525 0 R 3530 0 R 3536 0 R 3546 0 R 3551 0 R 3561 0 R 3572 0 R 3579 0 R 3584 0 R 3591 0 R 3596 0 R 3599 0 R 3607 0 R 3611 0 R 3616 0 R 3621 0 R 3634 0 R 3637 0 R 3643 0 R 3649 0 R 3654 0 R 3664 0 R 3673 0 R 3679 0 R 3688 0 R 3697 0 R 3702 0 R 3708 0 R 3714 0 R 3719 0 R 3721 0 R 3727 0 R 3734 0 R 3736 0 R 3744 0 R 3746 0 R 3752 0 R 3760 0 R 3766 0 R 3775 0 R 3781 0 R 3792 0 R 3801 0 R 3813 0 R 3823 0 R 3834 0 R 3838 0 R 3840 0 R 3844 0 R 3858 0 R 3864 0 R 3868 0 R 3874 0 R 3878 0 R 3881 0 R 3886 0 R 3888 0 R 3892 0 R 3894 0 R 3898 0 R 3901 0 R 3904 0 R 3912 0 R 3914 0 R 3920 0 R 3923 0 R 3929 0 R 3933 0 R 3936 0 R 3939 0 
 R 3942 0 R 3946 0 R 3949 0 R 3954 0 R 3959 0 R 3962 0 R 3970 0 R 3974 0 R 3978 0 R 3980 0 R 3983 0 R 3986 0 R 3991 0 R 3998 0 R 4004 0 R 4008 0 R 4011 0 R 4018 0 R 4026 0 R 4030 0 R 4033 0 R 4035 0 R 4039 0 R 4044 0 R 4049 0 R 4052 0 R 4061 0 R 4066 0 R 4070 0 R 4073 0 R 4081 0 R 4086 0 R 4094 0 R 4099 0 R 4101 0 R 4107 0 R 4109 0 R 4114 0 R 4118 0 R 4123 0 R 4127 0 R 4139 0 R 4155 0 R 4170 0 R 4175 0 R 4177 0 R 4179 0 R 4181 0 R 4183 0 R 4185 0 R 4194 0 R 4198 0 R 4202 0 R 4206 0 R 4208 0 R 4215 0 R 4225 0 R 4232 0 R 4235 0 R 4238 0 R 4240 0 R 4247 0 R 4254 0 R 4264 0 R 4268 0 R 4271 0 R 4275 0 R 4278 0 R 4284 0 R 4287 0 R 4302 0 R 4307 0 R 4330 0 R 4334 0 R 4341 0 R 4352 0 R 4361 0 R 4364 0 R 4367 0 R 4370 0 R 4386 0 R 4391 0 R 4398 0 R 4401 0 R 4404 0 R 4411 0 R 4416 0 R 4420 0 R 4422 0 R 4428 0 R 4435 0 R 4443 0 R 4447 0 R 4452 0 R 4457 0 R 4462 0 R 4469 0 R 4476 0 R 4483 0 R 4491 0 R 4499 0 R 4503 0 R 4512 0 R 4521 0 R 4527 0 R]
 >>
 endobj
 4 0 obj
@@ -187,11 +187,11 @@ endobj
 << /Type /Font
 /BaseFont /71be00+NotoSerif
 /Subtype /TrueType
-/FontDescriptor 5267 0 R
+/FontDescriptor 5280 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5269 0 R
-/ToUnicode 5268 0 R
+/Widths 5282 0 R
+/ToUnicode 5281 0 R
 >>
 endobj
 11 0 obj
@@ -1750,7 +1750,7 @@ endobj
 /F1.0 10 0 R
 >>
 >>
-/Annots [4515 0 R 4516 0 R 4517 0 R 4518 0 R 4519 0 R 4520 0 R 4521 0 R 4522 0 R 4523 0 R 4524 0 R 4525 0 R 4526 0 R 4527 0 R 4528 0 R 4529 0 R 4530 0 R 4531 0 R 4532 0 R 4533 0 R 4534 0 R 4535 0 R 4536 0 R 4537 0 R 4538 0 R 4539 0 R 4540 0 R 4541 0 R 4542 0 R 4543 0 R 4544 0 R 4545 0 R 4546 0 R 4547 0 R 4548 0 R 4549 0 R 4550 0 R 4551 0 R 4552 0 R 4553 0 R 4554 0 R 4555 0 R 4556 0 R 4557 0 R 4558 0 R 4559 0 R 4560 0 R 4561 0 R 4562 0 R 4563 0 R 4564 0 R 4565 0 R 4566 0 R 4567 0 R 4568 0 R 4569 0 R 4570 0 R 4571 0 R 4572 0 R 4573 0 R 4574 0 R 4575 0 R 4576 0 R 4577 0 R 4578 0 R 4579 0 R 4580 0 R 4581 0 R 4582 0 R 4583 0 R 4584 0 R 4585 0 R 4586 0 R 4587 0 R 4588 0 R 4589 0 R 4590 0 R]
+/Annots [4528 0 R 4529 0 R 4530 0 R 4531 0 R 4532 0 R 4533 0 R 4534 0 R 4535 0 R 4536 0 R 4537 0 R 4538 0 R 4539 0 R 4540 0 R 4541 0 R 4542 0 R 4543 0 R 4544 0 R 4545 0 R 4546 0 R 4547 0 R 4548 0 R 4549 0 R 4550 0 R 4551 0 R 4552 0 R 4553 0 R 4554 0 R 4555 0 R 4556 0 R 4557 0 R 4558 0 R 4559 0 R 4560 0 R 4561 0 R 4562 0 R 4563 0 R 4564 0 R 4565 0 R 4566 0 R 4567 0 R 4568 0 R 4569 0 R 4570 0 R 4571 0 R 4572 0 R 4573 0 R 4574 0 R 4575 0 R 4576 0 R 4577 0 R 4578 0 R 4579 0 R 4580 0 R 4581 0 R 4582 0 R 4583 0 R 4584 0 R 4585 0 R 4586 0 R 4587 0 R 4588 0 R 4589 0 R 4590 0 R 4591 0 R 4592 0 R 4593 0 R 4594 0 R 4595 0 R 4596 0 R 4597 0 R 4598 0 R 4599 0 R 4600 0 R 4601 0 R 4602 0 R 4603 0 R]
 >>
 endobj
 13 0 obj
@@ -3417,7 +3417,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [4591 0 R 4592 0 R 4593 0 R 4594 0 R 4595 0 R 4596 0 R 4597 0 R 4598 0 R 4599 0 R 4600 0 R 4601 0 R 4602 0 R 4603 0 R 4604 0 R 4605 0 R 4606 0 R 4607 0 R 4608 0 R 4609 0 R 4610 0 R 4611 0 R 4612 0 R 4613 0 R 4614 0 R 4615 0 R 4616 0 R 4617 0 R 4618 0 R 4619 0 R 4620 0 R 4621 0 R 4622 0 R 4623 0 R 4624 0 R 4625 0 R 4626 0 R 4627 0 R 4628 0 R 4629 0 R 4630 0 R 4631 0 R 4632 0 R 4633 0 R 4634 0 R 4635 0 R 4636 0 R 4637 0 R 4638 0 R 4639 0 R 4640 0 R 4641 0 R 4642 0 R 4643 0 R 4644 0 R 4645 0 R 4646 0 R 4647 0 R 4648 0 R 4649 0 R 4650 0 R 4651 0 R 4652 0 R 4653 0 R 4654 0 R 4655 0 R 4656 0 R 4657 0 R 4658 0 R 4659 0 R 4660 0 R 4661 0 R 4662 0 R 4663 0 R 4664 0 R 4665 0 R 4666 0 R 4667 0 R 4668 0 R 4669 0 R 4670 0 R 4671 0 R 4672 0 R]
+/Annots [4604 0 R 4605 0 R 4606 0 R 4607 0 R 4608 0 R 4609 0 R 4610 0 R 4611 0 R 4612 0 R 4613 0 R 4614 0 R 4615 0 R 4616 0 R 4617 0 R 4618 0 R 4619 0 R 4620 0 R 4621 0 R 4622 0 R 4623 0 R 4624 0 R 4625 0 R 4626 0 R 4627 0 R 4628 0 R 4629 0 R 4630 0 R 4631 0 R 4632 0 R 4633 0 R 4634 0 R 4635 0 R 4636 0 R 4637 0 R 4638 0 R 4639 0 R 4640 0 R 4641 0 R 4642 0 R 4643 0 R 4644 0 R 4645 0 R 4646 0 R 4647 0 R 4648 0 R 4649 0 R 4650 0 R 4651 0 R 4652 0 R 4653 0 R 4654 0 R 4655 0 R 4656 0 R 4657 0 R 4658 0 R 4659 0 R 4660 0 R 4661 0 R 4662 0 R 4663 0 R 4664 0 R 4665 0 R 4666 0 R 4667 0 R 4668 0 R 4669 0 R 4670 0 R 4671 0 R 4672 0 R 4673 0 R 4674 0 R 4675 0 R 4676 0 R 4677 0 R 4678 0 R 4679 0 R 4680 0 R 4681 0 R 4682 0 R 4683 0 R 4684 0 R 4685 0 R]
 >>
 endobj
 15 0 obj
@@ -5084,7 +5084,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [4673 0 R 4674 0 R 4675 0 R 4676 0 R 4677 0 R 4678 0 R 4679 0 R 4680 0 R 4681 0 R 4682 0 R 4683 0 R 4684 0 R 4685 0 R 4686 0 R 4687 0 R 4688 0 R 4689 0 R 4690 0 R 4691 0 R 4692 0 R 4693 0 R 4694 0 R 4695 0 R 4696 0 R 4697 0 R 4698 0 R 4699 0 R 4700 0 R 4701 0 R 4702 0 R 4703 0 R 4704 0 R 4705 0 R 4706 0 R 4707 0 R 4708 0 R 4709 0 R 4710 0 R 4711 0 R 4712 0 R 4713 0 R 4714 0 R 4715 0 R 4716 0 R 4717 0 R 4718 0 R 4719 0 R 4720 0 R 4721 0 R 4722 0 R 4723 0 R 4724 0 R 4725 0 R 4726 0 R 4727 0 R 4728 0 R 4729 0 R 4730 0 R 4731 0 R 4732 0 R 4733 0 R 4734 0 R 4735 0 R 4736 0 R 4737 0 R 4738 0 R 4739 0 R 4740 0 R 4741 0 R 4742 0 R 4743 0 R 4744 0 R 4745 0 R 4746 0 R 4747 0 R 4748 0 R 4749 0 R 4750 0 R 4751 0 R 4752 0 R 4753 0 R 4754 0 R]
+/Annots [4686 0 R 4687 0 R 4688 0 R 4689 0 R 4690 0 R 4691 0 R 4692 0 R 4693 0 R 4694 0 R 4695 0 R 4696 0 R 4697 0 R 4698 0 R 4699 0 R 4700 0 R 4701 0 R 4702 0 R 4703 0 R 4704 0 R 4705 0 R 4706 0 R 4707 0 R 4708 0 R 4709 0 R 4710 0 R 4711 0 R 4712 0 R 4713 0 R 4714 0 R 4715 0 R 4716 0 R 4717 0 R 4718 0 R 4719 0 R 4720 0 R 4721 0 R 4722 0 R 4723 0 R 4724 0 R 4725 0 R 4726 0 R 4727 0 R 4728 0 R 4729 0 R 4730 0 R 4731 0 R 4732 0 R 4733 0 R 4734 0 R 4735 0 R 4736 0 R 4737 0 R 4738 0 R 4739 0 R 4740 0 R 4741 0 R 4742 0 R 4743 0 R 4744 0 R 4745 0 R 4746 0 R 4747 0 R 4748 0 R 4749 0 R 4750 0 R 4751 0 R 4752 0 R 4753 0 R 4754 0 R 4755 0 R 4756 0 R 4757 0 R 4758 0 R 4759 0 R 4760 0 R 4761 0 R 4762 0 R 4763 0 R 4764 0 R 4765 0 R 4766 0 R 4767 0 R]
 >>
 endobj
 17 0 obj
@@ -6751,7 +6751,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [4755 0 R 4756 0 R 4757 0 R 4758 0 R 4759 0 R 4760 0 R 4761 0 R 4762 0 R 4763 0 R 4764 0 R 4765 0 R 4766 0 R 4767 0 R 4768 0 R 4769 0 R 4770 0 R 4771 0 R 4772 0 R 4773 0 R 4774 0 R 4775 0 R 4776 0 R 4777 0 R 4778 0 R 4779 0 R 4780 0 R 4781 0 R 4782 0 R 4783 0 R 4784 0 R 4785 0 R 4786 0 R 4787 0 R 4788 0 R 4789 0 R 4790 0 R 4791 0 R 4792 0 R 4793 0 R 4794 0 R 4795 0 R 4796 0 R 4797 0 R 4798 0 R 4799 0 R 4800 0 R 4801 0 R 4802 0 R 4803 0 R 4804 0 R 4805 0 R 4806 0 R 4807 0 R 4808 0 R 4809 0 R 4810 0 R 4811 0 R 4812 0 R 4813 0 R 4814 0 R 4815 0 R 4816 0 R 4817 0 R 4818 0 R 4819 0 R 4820 0 R 4821 0 R 4822 0 R 4823 0 R 4824 0 R 4825 0 R 4826 0 R 4827 0 R 4828 0 R 4829 0 R 4830 0 R 4831 0 R 4832 0 R 4833 0 R 4834 0 R 4835 0 R 4836 0 R]
+/Annots [4768 0 R 4769 0 R 4770 0 R 4771 0 R 4772 0 R 4773 0 R 4774 0 R 4775 0 R 4776 0 R 4777 0 R 4778 0 R 4779 0 R 4780 0 R 4781 0 R 4782 0 R 4783 0 R 4784 0 R 4785 0 R 4786 0 R 4787 0 R 4788 0 R 4789 0 R 4790 0 R 4791 0 R 4792 0 R 4793 0 R 4794 0 R 4795 0 R 4796 0 R 4797 0 R 4798 0 R 4799 0 R 4800 0 R 4801 0 R 4802 0 R 4803 0 R 4804 0 R 4805 0 R 4806 0 R 4807 0 R 4808 0 R 4809 0 R 4810 0 R 4811 0 R 4812 0 R 4813 0 R 4814 0 R 4815 0 R 4816 0 R 4817 0 R 4818 0 R 4819 0 R 4820 0 R 4821 0 R 4822 0 R 4823 0 R 4824 0 R 4825 0 R 4826 0 R 4827 0 R 4828 0 R 4829 0 R 4830 0 R 4831 0 R 4832 0 R 4833 0 R 4834 0 R 4835 0 R 4836 0 R 4837 0 R 4838 0 R 4839 0 R 4840 0 R 4841 0 R 4842 0 R 4843 0 R 4844 0 R 4845 0 R 4846 0 R 4847 0 R 4848 0 R 4849 0 R]
 >>
 endobj
 19 0 obj
@@ -7396,7 +7396,7 @@ ET
 BT
 529.4315 517.476 Td
 /F1.0 10.5 Tf
-<353630> Tj
+<353632> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7436,7 +7436,7 @@ ET
 BT
 529.4315 498.996 Td
 /F1.0 10.5 Tf
-<353733> Tj
+<353735> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7476,7 +7476,7 @@ ET
 BT
 529.4315 480.516 Td
 /F1.0 10.5 Tf
-<353831> Tj
+<353833> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7516,7 +7516,7 @@ ET
 BT
 529.4315 462.036 Td
 /F1.0 10.5 Tf
-<353833> Tj
+<353835> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7556,7 +7556,7 @@ ET
 BT
 529.4315 443.556 Td
 /F1.0 10.5 Tf
-<353837> Tj
+<353839> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7596,7 +7596,7 @@ ET
 BT
 529.4315 425.076 Td
 /F1.0 10.5 Tf
-<353838> Tj
+<353930> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7636,7 +7636,7 @@ ET
 BT
 529.4315 406.596 Td
 /F1.0 10.5 Tf
-<353932> Tj
+<353934> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7676,7 +7676,7 @@ ET
 BT
 529.4315 388.116 Td
 /F1.0 10.5 Tf
-<353933> Tj
+<353935> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7716,7 +7716,7 @@ ET
 BT
 529.4315 369.636 Td
 /F1.0 10.5 Tf
-<353937> Tj
+<353939> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7756,7 +7756,7 @@ ET
 BT
 529.4315 351.156 Td
 /F1.0 10.5 Tf
-<363032> Tj
+<363034> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7796,7 +7796,7 @@ ET
 BT
 529.4315 332.676 Td
 /F1.0 10.5 Tf
-<363033> Tj
+<363035> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7836,7 +7836,7 @@ ET
 BT
 529.4315 314.196 Td
 /F1.0 10.5 Tf
-<363036> Tj
+<363038> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7876,7 +7876,7 @@ ET
 BT
 529.4315 295.716 Td
 /F1.0 10.5 Tf
-<363037> Tj
+<363039> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7916,7 +7916,7 @@ ET
 BT
 529.4315 277.236 Td
 /F1.0 10.5 Tf
-<363130> Tj
+<363132> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7956,7 +7956,7 @@ ET
 BT
 529.4315 258.756 Td
 /F1.0 10.5 Tf
-<363134> Tj
+<363136> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -7996,7 +7996,7 @@ ET
 BT
 529.4315 240.276 Td
 /F1.0 10.5 Tf
-<363232> Tj
+<363234> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8036,7 +8036,7 @@ ET
 BT
 529.4315 221.796 Td
 /F1.0 10.5 Tf
-<363233> Tj
+<363235> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8076,7 +8076,7 @@ ET
 BT
 529.4315 203.316 Td
 /F1.0 10.5 Tf
-<363234> Tj
+<363236> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8127,7 +8127,7 @@ ET
 BT
 529.4315 184.836 Td
 /F1.0 10.5 Tf
-<363235> Tj
+<363237> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8167,7 +8167,7 @@ ET
 BT
 529.4315 166.356 Td
 /F1.0 10.5 Tf
-<363236> Tj
+<363238> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8207,7 +8207,7 @@ ET
 BT
 529.4315 147.876 Td
 /F1.0 10.5 Tf
-<363430> Tj
+<363432> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8247,7 +8247,7 @@ ET
 BT
 529.4315 129.396 Td
 /F1.0 10.5 Tf
-<363536> Tj
+<363538> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8287,7 +8287,7 @@ ET
 BT
 529.4315 110.916 Td
 /F1.0 10.5 Tf
-<363537> Tj
+<363539> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8327,7 +8327,7 @@ ET
 BT
 529.4315 92.436 Td
 /F1.0 10.5 Tf
-<363539> Tj
+<363631> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8367,7 +8367,7 @@ ET
 BT
 529.4315 73.956 Td
 /F1.0 10.5 Tf
-<363631> Tj
+<363633> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8407,7 +8407,7 @@ ET
 BT
 529.4315 55.476 Td
 /F1.0 10.5 Tf
-<363633> Tj
+<363635> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8429,7 +8429,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [4837 0 R 4838 0 R 4839 0 R 4840 0 R 4841 0 R 4842 0 R 4843 0 R 4844 0 R 4845 0 R 4846 0 R 4847 0 R 4848 0 R 4849 0 R 4850 0 R 4851 0 R 4852 0 R 4853 0 R 4854 0 R 4855 0 R 4856 0 R 4857 0 R 4858 0 R 4859 0 R 4860 0 R 4861 0 R 4862 0 R 4863 0 R 4864 0 R 4865 0 R 4866 0 R 4867 0 R 4868 0 R 4869 0 R 4870 0 R 4871 0 R 4872 0 R 4873 0 R 4874 0 R 4875 0 R 4876 0 R 4877 0 R 4878 0 R 4879 0 R 4880 0 R 4881 0 R 4882 0 R 4883 0 R 4884 0 R 4885 0 R 4886 0 R 4887 0 R 4888 0 R 4889 0 R 4890 0 R 4891 0 R 4892 0 R 4893 0 R 4894 0 R 4895 0 R 4896 0 R 4897 0 R 4898 0 R 4899 0 R 4900 0 R 4901 0 R 4902 0 R 4903 0 R 4904 0 R 4905 0 R 4906 0 R 4907 0 R 4908 0 R 4909 0 R 4910 0 R 4911 0 R 4912 0 R 4913 0 R 4914 0 R 4915 0 R 4916 0 R 4917 0 R 4918 0 R 4919 0 R 4920 0 R]
+/Annots [4850 0 R 4851 0 R 4852 0 R 4853 0 R 4854 0 R 4855 0 R 4856 0 R 4857 0 R 4858 0 R 4859 0 R 4860 0 R 4861 0 R 4862 0 R 4863 0 R 4864 0 R 4865 0 R 4866 0 R 4867 0 R 4868 0 R 4869 0 R 4870 0 R 4871 0 R 4872 0 R 4873 0 R 4874 0 R 4875 0 R 4876 0 R 4877 0 R 4878 0 R 4879 0 R 4880 0 R 4881 0 R 4882 0 R 4883 0 R 4884 0 R 4885 0 R 4886 0 R 4887 0 R 4888 0 R 4889 0 R 4890 0 R 4891 0 R 4892 0 R 4893 0 R 4894 0 R 4895 0 R 4896 0 R 4897 0 R 4898 0 R 4899 0 R 4900 0 R 4901 0 R 4902 0 R 4903 0 R 4904 0 R 4905 0 R 4906 0 R 4907 0 R 4908 0 R 4909 0 R 4910 0 R 4911 0 R 4912 0 R 4913 0 R 4914 0 R 4915 0 R 4916 0 R 4917 0 R 4918 0 R 4919 0 R 4920 0 R 4921 0 R 4922 0 R 4923 0 R 4924 0 R 4925 0 R 4926 0 R 4927 0 R 4928 0 R 4929 0 R 4930 0 R 4931 0 R 4932 0 R 4933 0 R]
 >>
 endobj
 21 0 obj
@@ -8474,7 +8474,7 @@ ET
 BT
 529.4315 794.676 Td
 /F1.0 10.5 Tf
-<363635> Tj
+<363637> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8514,7 +8514,7 @@ ET
 BT
 529.4315 776.196 Td
 /F1.0 10.5 Tf
-<363636> Tj
+<363638> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8565,7 +8565,7 @@ ET
 BT
 529.4315 757.716 Td
 /F1.0 10.5 Tf
-<363638> Tj
+<363730> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8605,7 +8605,7 @@ ET
 BT
 529.4315 739.236 Td
 /F1.0 10.5 Tf
-<363639> Tj
+<363731> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8645,7 +8645,7 @@ ET
 BT
 529.4315 720.756 Td
 /F1.0 10.5 Tf
-<363732> Tj
+<363734> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8685,7 +8685,7 @@ ET
 BT
 529.4315 702.276 Td
 /F1.0 10.5 Tf
-<363733> Tj
+<363735> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8725,7 +8725,7 @@ ET
 BT
 529.4315 683.796 Td
 /F1.0 10.5 Tf
-<363734> Tj
+<363736> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8765,7 +8765,7 @@ ET
 BT
 529.4315 665.316 Td
 /F1.0 10.5 Tf
-<363735> Tj
+<363737> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8805,7 +8805,7 @@ ET
 BT
 529.4315 646.836 Td
 /F1.0 10.5 Tf
-<363736> Tj
+<363738> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8845,7 +8845,7 @@ ET
 BT
 529.4315 628.356 Td
 /F1.0 10.5 Tf
-<363737> Tj
+<363739> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8885,7 +8885,7 @@ ET
 BT
 529.4315 609.876 Td
 /F1.0 10.5 Tf
-<363738> Tj
+<363830> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8925,7 +8925,7 @@ ET
 BT
 529.4315 591.396 Td
 /F1.0 10.5 Tf
-<363739> Tj
+<363831> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -8965,7 +8965,7 @@ ET
 BT
 529.4315 572.916 Td
 /F1.0 10.5 Tf
-<363830> Tj
+<363832> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9005,7 +9005,7 @@ ET
 BT
 529.4315 554.436 Td
 /F1.0 10.5 Tf
-<363831> Tj
+<363833> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9045,7 +9045,7 @@ ET
 BT
 529.4315 535.956 Td
 /F1.0 10.5 Tf
-<363832> Tj
+<363834> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9085,7 +9085,7 @@ ET
 BT
 529.4315 517.476 Td
 /F1.0 10.5 Tf
-<363834> Tj
+<363836> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9125,7 +9125,7 @@ ET
 BT
 529.4315 498.996 Td
 /F1.0 10.5 Tf
-<363835> Tj
+<363837> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9165,7 +9165,7 @@ ET
 BT
 529.4315 480.516 Td
 /F1.0 10.5 Tf
-<363836> Tj
+<363838> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9205,7 +9205,7 @@ ET
 BT
 529.4315 462.036 Td
 /F1.0 10.5 Tf
-<363837> Tj
+<363839> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9245,7 +9245,7 @@ ET
 BT
 529.4315 443.556 Td
 /F1.0 10.5 Tf
-<363838> Tj
+<363930> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9285,7 +9285,7 @@ ET
 BT
 529.4315 425.076 Td
 /F1.0 10.5 Tf
-<363839> Tj
+<363931> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9325,7 +9325,7 @@ ET
 BT
 529.4315 406.596 Td
 /F1.0 10.5 Tf
-<363931> Tj
+<363933> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9365,7 +9365,7 @@ ET
 BT
 529.4315 388.116 Td
 /F1.0 10.5 Tf
-<363932> Tj
+<363934> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9405,7 +9405,7 @@ ET
 BT
 529.4315 369.636 Td
 /F1.0 10.5 Tf
-<363939> Tj
+<373031> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9445,7 +9445,7 @@ ET
 BT
 529.4315 351.156 Td
 /F1.0 10.5 Tf
-<373030> Tj
+<373032> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9485,7 +9485,7 @@ ET
 BT
 529.4315 332.676 Td
 /F1.0 10.5 Tf
-<373031> Tj
+<373033> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9525,7 +9525,7 @@ ET
 BT
 529.4315 314.196 Td
 /F1.0 10.5 Tf
-<373032> Tj
+<373034> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9565,7 +9565,7 @@ ET
 BT
 529.4315 295.716 Td
 /F1.0 10.5 Tf
-<373033> Tj
+<373035> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9605,7 +9605,7 @@ ET
 BT
 529.4315 277.236 Td
 /F1.0 10.5 Tf
-<373034> Tj
+<373036> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9645,7 +9645,7 @@ ET
 BT
 529.4315 258.756 Td
 /F1.0 10.5 Tf
-<373135> Tj
+<373137> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9685,7 +9685,7 @@ ET
 BT
 529.4315 240.276 Td
 /F1.0 10.5 Tf
-<373138> Tj
+<373230> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9725,7 +9725,7 @@ ET
 BT
 529.4315 221.796 Td
 /F1.0 10.5 Tf
-<373234> Tj
+<373236> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9765,7 +9765,7 @@ ET
 BT
 529.4315 203.316 Td
 /F1.0 10.5 Tf
-<373335> Tj
+<373337> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9805,7 +9805,7 @@ ET
 BT
 529.4315 184.836 Td
 /F1.0 10.5 Tf
-<373336> Tj
+<373338> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9845,7 +9845,7 @@ ET
 BT
 529.4315 166.356 Td
 /F1.0 10.5 Tf
-<373337> Tj
+<373339> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9885,7 +9885,7 @@ ET
 BT
 529.4315 147.876 Td
 /F1.0 10.5 Tf
-<373436> Tj
+<373438> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9925,7 +9925,7 @@ ET
 BT
 529.4315 129.396 Td
 /F1.0 10.5 Tf
-<373437> Tj
+<373439> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -9965,7 +9965,7 @@ ET
 BT
 529.4315 110.916 Td
 /F1.0 10.5 Tf
-<373438> Tj
+<373530> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10005,7 +10005,7 @@ ET
 BT
 529.4315 92.436 Td
 /F1.0 10.5 Tf
-<373439> Tj
+<373531> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10045,7 +10045,7 @@ ET
 BT
 529.4315 73.956 Td
 /F1.0 10.5 Tf
-<373530> Tj
+<373532> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10085,7 +10085,7 @@ ET
 BT
 529.4315 55.476 Td
 /F1.0 10.5 Tf
-<373532> Tj
+<373534> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10107,7 +10107,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [4921 0 R 4922 0 R 4923 0 R 4924 0 R 4925 0 R 4926 0 R 4927 0 R 4928 0 R 4929 0 R 4930 0 R 4931 0 R 4932 0 R 4933 0 R 4934 0 R 4935 0 R 4936 0 R 4937 0 R 4938 0 R 4939 0 R 4940 0 R 4941 0 R 4942 0 R 4943 0 R 4944 0 R 4945 0 R 4946 0 R 4947 0 R 4948 0 R 4949 0 R 4950 0 R 4951 0 R 4952 0 R 4953 0 R 4954 0 R 4955 0 R 4956 0 R 4957 0 R 4958 0 R 4959 0 R 4960 0 R 4961 0 R 4962 0 R 4963 0 R 4964 0 R 4965 0 R 4966 0 R 4967 0 R 4968 0 R 4969 0 R 4970 0 R 4971 0 R 4972 0 R 4973 0 R 4974 0 R 4975 0 R 4976 0 R 4977 0 R 4978 0 R 4979 0 R 4980 0 R 4981 0 R 4982 0 R 4983 0 R 4984 0 R 4985 0 R 4986 0 R 4987 0 R 4988 0 R 4989 0 R 4990 0 R 4991 0 R 4992 0 R 4993 0 R 4994 0 R 4995 0 R 4996 0 R 4997 0 R 4998 0 R 4999 0 R 5000 0 R 5001 0 R 5002 0 R 5003 0 R 5004 0 R]
+/Annots [4934 0 R 4935 0 R 4936 0 R 4937 0 R 4938 0 R 4939 0 R 4940 0 R 4941 0 R 4942 0 R 4943 0 R 4944 0 R 4945 0 R 4946 0 R 4947 0 R 4948 0 R 4949 0 R 4950 0 R 4951 0 R 4952 0 R 4953 0 R 4954 0 R 4955 0 R 4956 0 R 4957 0 R 4958 0 R 4959 0 R 4960 0 R 4961 0 R 4962 0 R 4963 0 R 4964 0 R 4965 0 R 4966 0 R 4967 0 R 4968 0 R 4969 0 R 4970 0 R 4971 0 R 4972 0 R 4973 0 R 4974 0 R 4975 0 R 4976 0 R 4977 0 R 4978 0 R 4979 0 R 4980 0 R 4981 0 R 4982 0 R 4983 0 R 4984 0 R 4985 0 R 4986 0 R 4987 0 R 4988 0 R 4989 0 R 4990 0 R 4991 0 R 4992 0 R 4993 0 R 4994 0 R 4995 0 R 4996 0 R 4997 0 R 4998 0 R 4999 0 R 5000 0 R 5001 0 R 5002 0 R 5003 0 R 5004 0 R 5005 0 R 5006 0 R 5007 0 R 5008 0 R 5009 0 R 5010 0 R 5011 0 R 5012 0 R 5013 0 R 5014 0 R 5015 0 R 5016 0 R 5017 0 R]
 >>
 endobj
 23 0 obj
@@ -10152,7 +10152,7 @@ ET
 BT
 529.4315 794.676 Td
 /F1.0 10.5 Tf
-<373533> Tj
+<373535> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10192,7 +10192,7 @@ ET
 BT
 529.4315 776.196 Td
 /F1.0 10.5 Tf
-<373534> Tj
+<373536> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10232,7 +10232,7 @@ ET
 BT
 529.4315 757.716 Td
 /F1.0 10.5 Tf
-<373538> Tj
+<373630> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10272,7 +10272,7 @@ ET
 BT
 529.4315 739.236 Td
 /F1.0 10.5 Tf
-<373539> Tj
+<373631> Tj
 ET
 
 0.0 0.0 0.0 SCN
@@ -10294,7 +10294,7 @@ endobj
 /Font << /F1.0 10 0 R
 >>
 >>
-/Annots [5005 0 R 5006 0 R 5007 0 R 5008 0 R 5009 0 R 5010 0 R 5011 0 R 5012 0 R]
+/Annots [5018 0 R 5019 0 R 5020 0 R 5021 0 R 5022 0 R 5023 0 R 5024 0 R 5025 0 R]
 >>
 endobj
 25 0 obj
@@ -11106,7 +11106,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [32 0 R 33 0 R 34 0 R 36 0 R 38 0 R 39 0 R 41 0 R 42 0 R 43 0 R]
@@ -11121,7 +11121,7 @@ endobj
 >>
 endobj
 29 0 obj
-<< /Kids [651 0 R 3771 0 R 1982 0 R 652 0 R 3704 0 R 1193 0 R 2614 0 R 4008 0 R]
+<< /Kids [651 0 R 3784 0 R 1982 0 R 652 0 R 3717 0 R 1193 0 R 2614 0 R 4021 0 R]
 >>
 endobj
 30 0 obj
@@ -11131,11 +11131,11 @@ endobj
 << /Type /Font
 /BaseFont /309344+NotoSerif-Bold
 /Subtype /TrueType
-/FontDescriptor 5271 0 R
+/FontDescriptor 5284 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5273 0 R
-/ToUnicode 5272 0 R
+/Widths 5286 0 R
+/ToUnicode 5285 0 R
 >>
 endobj
 32 0 obj
@@ -11175,11 +11175,11 @@ endobj
 << /Type /Font
 /BaseFont /fbe45d+NotoSerif-Italic
 /Subtype /TrueType
-/FontDescriptor 5275 0 R
+/FontDescriptor 5288 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5277 0 R
-/ToUnicode 5276 0 R
+/Widths 5290 0 R
+/ToUnicode 5289 0 R
 >>
 endobj
 36 0 obj
@@ -11197,11 +11197,11 @@ endobj
 << /Type /Font
 /BaseFont /c7d210+mplus1mn-regular
 /Subtype /TrueType
-/FontDescriptor 5279 0 R
+/FontDescriptor 5292 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5281 0 R
-/ToUnicode 5280 0 R
+/Widths 5294 0 R
+/ToUnicode 5293 0 R
 >>
 endobj
 38 0 obj
@@ -11227,11 +11227,11 @@ endobj
 << /Type /Font
 /BaseFont /6bc580+NotoSerif
 /Subtype /TrueType
-/FontDescriptor 5283 0 R
+/FontDescriptor 5296 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5285 0 R
-/ToUnicode 5284 0 R
+/Widths 5298 0 R
+/ToUnicode 5297 0 R
 >>
 endobj
 41 0 obj
@@ -11665,7 +11665,7 @@ endobj
 /F5.1 47 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -11674,11 +11674,11 @@ endobj
 << /Type /Font
 /BaseFont /26ec65+FontAwesome
 /Subtype /TrueType
-/FontDescriptor 5287 0 R
+/FontDescriptor 5300 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5289 0 R
-/ToUnicode 5288 0 R
+/Widths 5302 0 R
+/ToUnicode 5301 0 R
 >>
 endobj
 48 0 obj
@@ -11736,7 +11736,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -11821,7 +11821,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [54 0 R]
@@ -13394,7 +13394,7 @@ endobj
 /F1.1 40 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [59 0 R 61 0 R]
@@ -14514,7 +14514,7 @@ endobj
 /F1.0 10 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -15393,7 +15393,7 @@ endobj
 /F3.0 35 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [66 0 R]
@@ -16183,7 +16183,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -16902,7 +16902,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -17778,7 +17778,7 @@ endobj
 /F2.0 31 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [75 0 R 76 0 R 77 0 R 78 0 R]
@@ -18768,7 +18768,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [81 0 R]
@@ -19691,7 +19691,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -21202,7 +21202,7 @@ endobj
 /F4.0 37 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [86 0 R 88 0 R]
@@ -22550,7 +22550,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [92 0 R]
@@ -23624,7 +23624,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -24347,7 +24347,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -24986,7 +24986,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [99 0 R 100 0 R 101 0 R 103 0 R]
@@ -25230,7 +25230,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [107 0 R 108 0 R 109 0 R 110 0 R]
@@ -26102,7 +26102,7 @@ endobj
 /F4.0 37 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [114 0 R 115 0 R]
@@ -26382,7 +26382,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -27862,7 +27862,7 @@ endobj
 /F5.1 47 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [122 0 R 123 0 R 124 0 R 125 0 R 126 0 R 127 0 R 128 0 R 130 0 R 131 0 R 132 0 R 133 0 R]
@@ -28902,7 +28902,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [136 0 R 138 0 R]
@@ -29655,7 +29655,7 @@ endobj
 /F2.0 31 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [141 0 R 143 0 R 144 0 R 145 0 R 146 0 R]
@@ -33625,7 +33625,7 @@ endobj
 /F2.0 31 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [149 0 R 150 0 R 151 0 R 152 0 R 153 0 R 154 0 R 155 0 R]
@@ -34582,7 +34582,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [158 0 R 159 0 R 163 0 R]
@@ -34615,12 +34615,12 @@ endobj
 endobj
 161 0 obj
 << /Limits [(HBCK2) (adding.new.node)]
-/Names [(HBCK2) 3085 0 R (__anchor-top) 27 0 R (__indexterm-2002) 3669 0 R (__indexterm-2004) 3671 0 R (__indexterm-2006) 3673 0 R (__indexterm-2008) 3676 0 R (accesscontrolclient-changes) 4512 0 R (acid) 966 0 R (acl) 3471 0 R (add-metric-name-and-function-to-hadoop-compat-interface) 3773 0 R (add-the-implementation-to-both-hadoop-1-and-hadoop-2-compat-modules) 3774 0 R (add.metrics) 3769 0 R (adding-a-new-chapter-to-the-hbase-reference-guide) 4111 0 R (adding.new.node) 3215 0 R]
+/Names [(HBCK2) 3085 0 R (__anchor-top) 27 0 R (__indexterm-2002) 3682 0 R (__indexterm-2004) 3684 0 R (__indexterm-2006) 3686 0 R (__indexterm-2008) 3689 0 R (accesscontrolclient-changes) 4525 0 R (acid) 966 0 R (acl) 3485 0 R (add-metric-name-and-function-to-hadoop-compat-interface) 3786 0 R (add-the-implementation-to-both-hadoop-1-and-hadoop-2-compat-modules) 3787 0 R (add.metrics) 3782 0 R (adding-a-new-chapter-to-the-hbase-reference-guide) 4124 0 R (adding.new.node) 3215 0 R]
 >>
 endobj
 162 0 obj
 << /Limits [(io.storefile.bloom.block.size) (jdk-version-requirements)]
-/Names [(io.storefile.bloom.block.size) 365 0 R (ipc) 4419 0 R (irbrc) 829 0 R (irc) 3503 0 R (isolate-system-tables) 3465 0 R (java) 121 0 R (java-2) 1985 0 R (java-3) 1990 0 R (java.client.config) 526 0 R (jdk-issues) 2993 0 R (jdk-version-requirements) 58 0 R]
+/Names [(io.storefile.bloom.block.size) 365 0 R (ipc) 4432 0 R (irbrc) 829 0 R (irc) 3516 0 R (isolate-system-tables) 3479 0 R (java) 121 0 R (java-2) 1985 0 R (java-3) 1990 0 R (java.client.config) 526 0 R (jdk-issues) 2993 0 R (jdk-version-requirements) 58 0 R]
 >>
 endobj
 163 0 obj
@@ -34742,7 +34742,7 @@ endobj
 /F1.0 10 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [166 0 R]
@@ -35876,7 +35876,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [171 0 R 172 0 R 174 0 R]
@@ -36676,7 +36676,7 @@ endobj
 /F5.1 47 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [179 0 R 180 0 R 181 0 R 183 0 R 184 0 R 186 0 R 187 0 R]
@@ -38148,7 +38148,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [190 0 R 191 0 R]
@@ -38573,7 +38573,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -39229,7 +39229,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [197 0 R]
@@ -39996,7 +39996,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [202 0 R]
@@ -40527,7 +40527,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -40543,7 +40543,7 @@ endobj
 endobj
 212 0 obj
 << /Limits [(getshortmidpointkey-an-optimization-for-data-index-block) (handling-of-errors-during-log-splitting)]
-/Names [(getshortmidpointkey-an-optimization-for-data-index-block) 4272 0 R (getting.involved) 3492 0 R (getting_started) 50 0 R (git.best.practices) 3775 0 R (git.patch.flow) 3837 0 R (goals) 4365 0 R (guide-for-hbase-committers) 3802 0 R (guidelines-for-deploying-a-coprocessor) 2452 0 R (guidelines-for-reporting-effective-issues) 3510 0 R (hadoop) 142 0 R (hadoop.native.lib) 4191 0 R (hadoop.policy.file) 391 0 R (handling-of-errors-during-log-splitting) 1723 0 R]
+/Names [(getshortmidpointkey-an-optimization-for-data-index-block) 4285 0 R (getting.involved) 3506 0 R (getting_started) 50 0 R (git.best.practices) 3788 0 R (git.patch.flow) 3850 0 R (goals) 4378 0 R (guide-for-hbase-committers) 3815 0 R (guidelines-for-deploying-a-coprocessor) 2452 0 R (guidelines-for-reporting-effective-issues) 3523 0 R (hadoop) 142 0 R (hadoop.native.lib) 4204 0 R (hadoop.policy.file) 391 0 R (handling-of-errors-during-log-splitting) 1723 0 R]
 >>
 endobj
 213 0 obj
@@ -41073,7 +41073,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -41595,7 +41595,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -42230,7 +42230,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -42739,7 +42739,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -43270,7 +43270,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -43849,7 +43849,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [258 0 R 259 0 R]
@@ -44416,7 +44416,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [267 0 R 268 0 R 270 0 R 271 0 R]
@@ -44480,7 +44480,7 @@ endobj
 endobj
 274 0 obj
 << /Limits [(hbase.table.lock.enable) (hbase.tmp.dir)]
-/Names [(hbase.table.lock.enable) 418 0 R (hbase.table.max.rowsize) 419 0 R (hbase.tags) 1385 0 R (hbase.tests) 3652 0 R (hbase.tests.categories) 3696 0 R (hbase.tests.cluster) 3698 0 R (hbase.tests.example.code) 3699 0 R (hbase.tests.rules) 3692 0 R (hbase.tests.sleeps) 3697 0 R (hbase.tests.writing) 3691 0 R (hbase.thrift.maxQueuedRequests) 423 0 R (hbase.thrift.maxWorkerThreads) 422 0 R (hbase.thrift.minWorkerThreads) 421 0 R (hbase.tmp.dir) 204 0 R]
+/Names [(hbase.table.lock.enable) 418 0 R (hbase.table.max.rowsize) 419 0 R (hbase.tags) 1385 0 R (hbase.tests) 3665 0 R (hbase.tests.categories) 3709 0 R (hbase.tests.cluster) 3711 0 R (hbase.tests.example.code) 3712 0 R (hbase.tests.rules) 3705 0 R (hbase.tests.sleeps) 3710 0 R (hbase.tests.writing) 3704 0 R (hbase.thrift.maxQueuedRequests) 423 0 R (hbase.thrift.maxWorkerThreads) 422 0 R (hbase.thrift.minWorkerThreads) 421 0 R (hbase.tmp.dir) 204 0 R]
 >>
 endobj
 275 0 obj
@@ -45036,7 +45036,7 @@ endobj
 /F1.0 10 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -45631,7 +45631,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [291 0 R 292 0 R]
@@ -45651,7 +45651,7 @@ endobj
 endobj
 290 0 obj
 << /Limits [(hbase.cluster.distributed) (hbase.data.umask.enable)]
-/Names [(hbase.cluster.distributed) 206 0 R (hbase.column.max.version) 445 0 R (hbase.commit.msg.format) 4054 0 R (hbase.coordinated.state.manager.class) 485 0 R (hbase.coprocessor.abortonerror) 407 0 R (hbase.coprocessor.enabled) 402 0 R (hbase.coprocessor.master.classes) 406 0 R (hbase.coprocessor.region.classes) 405 0 R (hbase.coprocessor.user.enabled) 404 0 R (hbase.data.umask) 433 0 R (hbase.data.umask.enable) 432 0 R]
+/Names [(hbase.cluster.distributed) 206 0 R (hbase.column.max.version) 445 0 R (hbase.commit.msg.format) 4067 0 R (hbase.coordinated.state.manager.class) 485 0 R (hbase.coprocessor.abortonerror) 407 0 R (hbase.coprocessor.enabled) 402 0 R (hbase.coprocessor.master.classes) 406 0 R (hbase.coprocessor.region.classes) 405 0 R (hbase.coprocessor.user.enabled) 404 0 R (hbase.data.umask) 433 0 R (hbase.data.umask.enable) 432 0 R]
 >>
 endobj
 291 0 obj
@@ -46197,7 +46197,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -46688,7 +46688,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -47260,7 +47260,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -47806,7 +47806,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -48383,7 +48383,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -49003,7 +49003,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -49550,7 +49550,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -50073,7 +50073,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -50633,7 +50633,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [357 0 R]
@@ -51168,7 +51168,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [363 0 R]
@@ -51193,7 +51193,7 @@ endobj
 endobj
 366 0 obj
 << /Limits [(quota) (regions.arch)]
-/Names [(quota) 3326 0 R (read-api-and-usage) 1986 0 R (read-hbase-shell-commands-from-a-command-file) 815 0 R (reading-filtering-and-sending-edits) 3306 0 R (reading_cells_with_labels) 1439 0 R (recommended.configurations.hdfs) 554 0 R (recommended_configurations) 549 0 R (recommended_configurations.zk) 550 0 R (references) 3942 0 R (region-replication-for-meta-table-s-region) 1963 0 R (region-scanner-changes) 4491 0 R (region-transition-rpc-and-rs-heartbeat-can-arrive-at-same-time-on-master) 3975 0 R (regioncoprocessorenvironment-getregion-abstract-hregion) 4416 0 R (regioncoprocessorhost-postappend-append-append-result-result-void) 4417 0 R (regioncoprocessorhost-prestorefilereaderopen-filesystem-fs-path-p-fsdatainputstreamwrapper-in-long-size-cacheconfig-cacheconf-reference-r-storefile-reader) 4418 0 R (regionobserver) 4404 0 R (regions.arch) 1757 0 R]
+/Names [(quota) 3339 0 R (read-api-and-usage) 1986 0 R (read-hbase-shell-commands-from-a-command-file) 815 0 R (reading-filtering-and-sending-edits) 3319 0 R (reading_cells_with_labels) 1439 0 R (recommended.configurations.hdfs) 554 0 R (recommended_configurations) 549 0 R (recommended_configurations.zk) 550 0 R (references) 3955 0 R (region-replication-for-meta-table-s-region) 1963 0 R (region-scanner-changes) 4504 0 R (region-transition-rpc-and-rs-heartbeat-can-arrive-at-same-time-on-master) 3988 0 R (regioncoprocessorenvironment-getregion-abstract-hregion) 4429 0 R (regioncoprocessorhost-postappend-append-append-result-result-void) 4430 0 R (regioncoprocessorhost-prestorefilereaderopen-filesystem-fs-path-p-fsdatainputstreamwrapper-in-long-size-cacheconfig-cacheconf-reference-r-storefile-reader) 4431 0 R (regionobserver) 4417 0 R (regions.arch) 1757 0 R]
 >>
 endobj
 367 0 obj
@@ -51832,7 +51832,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [377 0 R 378 0 R 380 0 R 383 0 R 384 0 R]
@@ -51843,7 +51843,7 @@ endobj
 endobj
 375 0 obj
 << /Limits [(hbase.regionserver.thrift.compact) (hbase.rootdir.perms)]
-/Names [(hbase.regionserver.thrift.compact) 428 0 R (hbase.regionserver.thrift.framed) 424 0 R (hbase.regionserver.thrift.framed.max_frame_size_in_mb) 427 0 R (hbase.release.announcement) 3631 0 R (hbase.replication.management) 3276 0 R (hbase.replication.rpc.codec) 496 0 R (hbase.replication.source.maxthreads) 497 0 R (hbase.rest-csrf.browser-useragents-regex) 478 0 R (hbase.rest.csrf.enabled) 477 0 R (hbase.rest.filter.classes) 468 0 R (hbase.rest.port) 410 0 R (hbase.rest.readonly) 411 0 R (hbase.rest.support.proxyuser) 414 0 R (hbase.rest.threads.max) 412 0 R (hbase.rest.threads.min) 413 0 R (hbase.rolling.restart) 643 0 R (hbase.rolling.upgrade) 639 0 R (hbase.rootdir) 205 0 R (hbase.rootdir.perms) 429 0 R]
+/Names [(hbase.regionserver.thrift.compact) 428 0 R (hbase.regionserver.thrift.framed) 424 0 R (hbase.regionserver.thrift.framed.max_frame_size_in_mb) 427 0 R (hbase.release.announcement) 3644 0 R (hbase.replication.management) 3289 0 R (hbase.replication.rpc.codec) 496 0 R (hbase.replication.source.maxthreads) 497 0 R (hbase.rest-csrf.browser-useragents-regex) 478 0 R (hbase.rest.csrf.enabled) 477 0 R (hbase.rest.filter.classes) 468 0 R (hbase.rest.port) 410 0 R (hbase.rest.readonly) 411 0 R (hbase.rest.support.proxyuser) 414 0 R (hbase.rest.threads.max) 412 0 R (hbase.rest.threads.min) 413 0 R (hbase.rolling.restart) 643 0 R (hbase.rolling.upgrade) 639 0 R (hbase.rootdir) 205 0 R (hbase.rootdir.perms) 429 0 R]
 >>
 endobj
 376 0 obj
@@ -52422,7 +52422,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -52956,7 +52956,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -53506,7 +53506,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -54026,7 +54026,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -54559,7 +54559,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -55047,7 +55047,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -55063,7 +55063,7 @@ endobj
 endobj
 430 0 obj
 << /Limits [(hbase.rpc) (hbase.secure.spnego.ui)]
-/Names [(hbase.rpc) 4358 0 R (hbase.rpc.rows.warning.threshold) 517 0 R (hbase.rpc.shortoperation.timeout) 374 0 R (hbase.rpc.timeout) 368 0 R (hbase.rs.cacheblocksonwrite) 367 0 R (hbase.secure.bulkload) 1465 0 R (hbase.secure.configuration) 1305 0 R (hbase.secure.enable) 1469 0 R (hbase.secure.simpleconfiguration) 1347 0 R (hbase.secure.spnego.ui) 1300 0 R]
+/Names [(hbase.rpc) 4371 0 R (hbase.rpc.rows.warning.threshold) 517 0 R (hbase.rpc.shortoperation.timeout) 374 0 R (hbase.rpc.timeout) 368 0 R (hbase.rs.cacheblocksonwrite) 367 0 R (hbase.secure.bulkload) 1465 0 R (hbase.secure.configuration) 1305 0 R (hbase.secure.enable) 1469 0 R (hbase.secure.simpleconfiguration) 1347 0 R (hbase.secure.spnego.ui) 1300 0 R]
 >>
 endobj
 431 0 obj
@@ -55585,7 +55585,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -56130,7 +56130,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -56680,7 +56680,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -57168,7 +57168,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -57763,7 +57763,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [471 0 R 472 0 R 475 0 R 476 0 R]
@@ -58416,7 +58416,7 @@ endobj
 /F4.0 37 0 R
 /F6.0 481 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -58425,11 +58425,11 @@ endobj
 << /Type /Font
 /BaseFont /03fbbc+mplus1mn-bold
 /Subtype /TrueType
-/FontDescriptor 5291 0 R
+/FontDescriptor 5304 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5293 0 R
-/ToUnicode 5292 0 R
+/Widths 5306 0 R
+/ToUnicode 5305 0 R
 >>
 endobj
 482 0 obj
@@ -58446,7 +58446,7 @@ endobj
 endobj
 486 0 obj
 << /Limits [(hbase.defaults.for.version.skip) (hbase.hregion.percolumnfamilyflush.size.lower.bound.min)]
-/Names [(hbase.defaults.for.version.skip) 415 0 R (hbase.dfs.client.read.shortcircuit.buffer.size) 448 0 R (hbase.display.keys) 399 0 R (hbase.dynamic.jars.dir) 464 0 R (hbase.encryption.server) 1452 0 R (hbase.env.sh) 521 0 R (hbase.fix.version.in.jira) 4042 0 R (hbase.history) 4318 0 R (hbase.hregion.majorcompaction) 320 0 R (hbase.hregion.majorcompaction.jitter) 321 0 R (hbase.hregion.max.filesize) 319 0 R (hbase.hregion.memstore.block.multiplier) 315 0 R (hbase.hregion.memstore.flush.size) 312 0 R (hbase.hregion.memstore.mslab.enabled) 316 0 R (hbase.hregion.percolumnfamilyflush.size.lower.bound.min) 313 0 R]
+/Names [(hbase.defaults.for.version.skip) 415 0 R (hbase.dfs.client.read.shortcircuit.buffer.size) 448 0 R (hbase.display.keys) 399 0 R (hbase.dynamic.jars.dir) 464 0 R (hbase.encryption.server) 1452 0 R (hbase.env.sh) 521 0 R (hbase.fix.version.in.jira) 4055 0 R (hbase.history) 4331 0 R (hbase.hregion.majorcompaction) 320 0 R (hbase.hregion.majorcompaction.jitter) 321 0 R (hbase.hregion.max.filesize) 319 0 R (hbase.hregion.memstore.block.multiplier) 315 0 R (hbase.hregion.memstore.flush.size) 312 0 R (hbase.hregion.memstore.mslab.enabled) 316 0 R (hbase.hregion.percolumnfamilyflush.size.lower.bound.min) 313 0 R]
 >>
 endobj
 487 0 obj
@@ -58998,7 +58998,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -59525,7 +59525,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -60070,7 +60070,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -60089,7 +60089,7 @@ endobj
 endobj
 508 0 obj
 << /Limits [(hbase.moduletest.run) (hbase.procedure.store.wal.max.retries.before.roll)]
-/Names [(hbase.moduletest.run) 3661 0 R (hbase.moduletest.shell) 3656 0 R (hbase.moduletests) 3654 0 R (hbase.normalizer.min.region.count) 306 0 R (hbase.normalizer.period) 305 0 R (hbase.offpeak.end.hour) 342 0 R (hbase.offpeak.start.hour) 341 0 R (hbase.org) 3642 0 R (hbase.org.site.contributing) 3644 0 R (hbase.org.site.publishing) 3647 0 R (hbase.private.api) 635 0 R (hbase.procedure.master.classes) 484 0 R (hbase.procedure.regionserver.classes) 483 0 R (hbase.procedure.store.wal.max.retries.before.roll) 1616 0 R]
+/Names [(hbase.moduletest.run) 3674 0 R (hbase.moduletest.shell) 3669 0 R (hbase.moduletests) 3667 0 R (hbase.normalizer.min.region.count) 306 0 R (hbase.normalizer.period) 305 0 R (hbase.offpeak.end.hour) 342 0 R (hbase.offpeak.start.hour) 341 0 R (hbase.org) 3655 0 R (hbase.org.site.contributing) 3657 0 R (hbase.org.site.publishing) 3660 0 R (hbase.private.api) 635 0 R (hbase.procedure.master.classes) 484 0 R (hbase.procedure.regionserver.classes) 483 0 R (hbase.procedure.store.wal.max.retries.before.roll) 1616 0 R]
 >>
 endobj
 509 0 obj
@@ -60536,7 +60536,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -61357,7 +61357,7 @@ endobj
 /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -62695,7 +62695,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [527 0 R 528 0 R]
@@ -64166,7 +64166,7 @@ endobj
 /F3.0 35 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -64690,7 +64690,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -65343,7 +65343,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [543 0 R 544 0 R 546 0 R 547 0 R 548 0 R 553 0 R]
@@ -66098,7 +66098,7 @@ endobj
 /F2.0 31 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [559 0 R 562 0 R 565 0 R]
@@ -66137,7 +66137,7 @@ endobj
 endobj
 564 0 obj
 << /Limits [(configuration) (coprocessor-implementation-overview)]
-/Names [(configuration) 106 0 R (configuration-2) 3247 0 R (configuration-3) 4129 0 R (configuration-files) 113 0 R (configuration-from-scratch) 4027 0 R (configuration-properties) 1968 0 R (configure-mob-compaction-mergeable-threshold) 2009 0 R (configure-mob-compaction-policy) 2008 0 R (configuring-columns-for-mob) 2005 0 R (configuring-server-wide-behavior-of-bloom-filters) 2576 0 R (configuring-the-rest-server-and-client) 2225 0 R (confirm) 196 0 R (connection-setup) 4370 0 R (constraints) 1104 0 R (contributing-to-documentation-or-other-strings) 4065 0 R (coprocessor-api-changes) 4394 0 R (coprocessor-implementation-overview) 2381 0 R]
+/Names [(configuration) 106 0 R (configuration-2) 3247 0 R (configuration-3) 4142 0 R (configuration-files) 113 0 R (configuration-from-scratch) 4040 0 R (configuration-properties) 1968 0 R (configure-mob-compaction-mergeable-threshold) 2009 0 R (configure-mob-compaction-policy) 2008 0 R (configuring-columns-for-mob) 2005 0 R (configuring-server-wide-behavior-of-bloom-filters) 2576 0 R (configuring-the-rest-server-and-client) 2225 0 R (confirm) 196 0 R (connection-setup) 4383 0 R (constraints) 1104 0 R (contributing-to-documentation-or-other-strings) 4078 0 R (coprocessor-api-changes) 4407 0 R (coprocessor-implementation-overview) 2381 0 R]
 >>
 endobj
 565 0 obj
@@ -66999,7 +66999,7 @@ endobj
 /F4.0 37 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [569 0 R]
@@ -67813,7 +67813,7 @@ endobj
 /F5.1 47 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [573 0 R 574 0 R 575 0 R 579 0 R 582 0 R 583 0 R 584 0 R]
@@ -68555,7 +68555,7 @@ endobj
 /F1.1 40 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [588 0 R 589 0 R]
@@ -69987,7 +69987,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [593 0 R 594 0 R]
@@ -70764,7 +70764,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -71465,7 +71465,7 @@ endobj
 /F3.0 35 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -72796,7 +72796,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -74291,7 +74291,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -74613,7 +74613,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -74811,7 +74811,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [609 0 R 610 0 R 611 0 R 612 0 R 613 0 R]
@@ -75565,7 +75565,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [618 0 R]
@@ -76482,7 +76482,7 @@ endobj
 /F3.0 35 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [622 0 R]
@@ -78797,7 +78797,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [625 0 R 626 0 R]
@@ -79830,7 +79830,7 @@ endobj
 /F1.1 40 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [630 0 R 631 0 R 632 0 R]
@@ -80494,7 +80494,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [640 0 R 641 0 R 642 0 R 644 0 R 645 0 R 646 0 R]
@@ -81289,7 +81289,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [654 0 R]
@@ -81300,17 +81300,17 @@ endobj
 endobj
 650 0 obj
 << /Limits [(standalone.over.hdfs) (store.memstore)]
-/Names [(standalone.over.hdfs) 175 0 R (standalone_dist) 170 0 R (starting-and-stopping-the-rest-server) 2224 0 R (statemachineprocedure) 3938 0 R (static-loading) 2415 0 R (static-unloading) 2418 0 R (step-1-hashtable) 3111 0 R (step-2-synctable) 3115 0 R (store) 1808 0 R (store-file-ttl) 1962 0 R (store.file.dir) 1824 0 R (store.memstore) 1809 0 R]
+/Names [(standalone.over.hdfs) 175 0 R (standalone_dist) 170 0 R (starting-and-stopping-the-rest-server) 2224 0 R (statemachineprocedure) 3951 0 R (static-loading) 2415 0 R (static-unloading) 2418 0 R (step-1-hashtable) 3111 0 R (step-2-synctable) 3115 0 R (store) 1808 0 R (store-file-ttl) 1962 0 R (store.file.dir) 1824 0 R (store.memstore) 1809 0 R]
 >>
 endobj
 651 0 obj
 << /Limits [(HBCK2) (build.thrift)]
-/Kids [161 0 R 3770 0 R 4452 0 R 1926 0 R 1489 0 R 3725 0 R 1667 0 R 4267 0 R 2158 0 R 2116 0 R 2073 0 R 2107 0 R]
+/Kids [161 0 R 3783 0 R 4465 0 R 1926 0 R 1489 0 R 3738 0 R 1667 0 R 4280 0 R 2158 0 R 2116 0 R 2073 0 R 2107 0 R]
 >>
 endobj
 652 0 obj
 << /Limits [(hbase.moduletest.run) (hbase.zookeeper.property.initLimit)]
-/Kids [508 0 R 3645 0 R 382 0 R 245 0 R 375 0 R 430 0 R 4359 0 R 462 0 R 274 0 R 3693 0 R 3664 0 R]
+/Kids [508 0 R 3658 0 R 382 0 R 245 0 R 375 0 R 430 0 R 4372 0 R 462 0 R 274 0 R 3706 0 R 3677 0 R]
 >>
 endobj
 653 0 obj
@@ -81974,7 +81974,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -82689,7 +82689,7 @@ endobj
 /F1.0 10 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [662 0 R]
@@ -83156,7 +83156,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -83973,7 +83973,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [671 0 R 673 0 R 674 0 R 675 0 R 677 0 R]
@@ -85263,7 +85263,7 @@ endobj
 /F3.0 35 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [680 0 R 681 0 R 682 0 R 683 0 R 684 0 R 685 0 R 686 0 R 687 0 R 690 0 R 691 0 R]
@@ -86173,7 +86173,7 @@ endobj
 /Font << /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [694 0 R 695 0 R 696 0 R]
@@ -87072,7 +87072,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [701 0 R 704 0 R 705 0 R 707 0 R 709 0 R 710 0 R]
@@ -87932,7 +87932,7 @@ endobj
 /Font << /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [713 0 R 716 0 R 719 0 R 720 0 R]
@@ -88936,7 +88936,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [725 0 R 727 0 R 729 0 R]
@@ -89760,7 +89760,7 @@ endobj
 /F3.0 35 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [734 0 R 740 0 R 741 0 R 742 0 R]
@@ -90728,7 +90728,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [748 0 R 749 0 R 750 0 R 752 0 R 753 0 R 754 0 R 756 0 R 758 0 R 759 0 R 760 0 R 761 0 R]
@@ -91963,7 +91963,7 @@ endobj
 /F2.0 31 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 775 0 R 776 0 R 777 0 R 778 0 R]
@@ -92854,7 +92854,7 @@ endobj
 /F5.1 47 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [781 0 R 782 0 R]
@@ -93327,7 +93327,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [791 0 R]
@@ -93696,7 +93696,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [796 0 R 797 0 R 798 0 R]
@@ -93897,7 +93897,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -94135,7 +94135,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [805 0 R]
@@ -94731,7 +94731,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [809 0 R]
@@ -95268,7 +95268,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -95518,7 +95518,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -96002,7 +96002,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -96277,7 +96277,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -96714,7 +96714,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -97277,7 +97277,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -97888,7 +97888,7 @@ endobj
 /F3.0 35 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -99058,7 +99058,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [833 0 R]
@@ -99080,7 +99080,7 @@ endobj
 endobj
 835 0 obj
 << /Limits [(multiple-typed-queues) (new-system)]
-/Names [(multiple-typed-queues) 3339 0 R (multiwal) 1715 0 R (nagles) 581 0 R (namespace) 863 0 R (namespace_creation) 867 0 R (namespace_quotas) 3335 0 R (namespace_special) 868 0 R (network-saturation-the-winner) 3023 0 R (new-committers) 3812 0 R (new-configs) 3979 0 R (new-system) 3958 0 R]
+/Names [(multiple-typed-queues) 3352 0 R (multiwal) 1715 0 R (nagles) 581 0 R (namespace) 863 0 R (namespace_creation) 867 0 R (namespace_quotas) 3348 0 R (namespace_special) 868 0 R (network-saturation-the-winner) 3023 0 R (new-committers) 3825 0 R (new-configs) 3992 0 R (new-system) 3971 0 R]
 >>
 endobj
 836 0 obj
@@ -104344,7 +104344,7 @@ endobj
 /F2.0 31 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -104720,7 +104720,7 @@ endobj
 /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -105335,7 +105335,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -107876,7 +107876,7 @@ endobj
 /F5.1 47 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [852 0 R 853 0 R 854 0 R]
@@ -110895,7 +110895,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -112329,7 +112329,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [860 0 R]
@@ -113113,7 +113113,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [864 0 R 865 0 R 866 0 R]
@@ -113315,7 +113315,7 @@ endobj
 /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -113386,7 +113386,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -113490,7 +113490,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -113907,7 +113907,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -114027,7 +114027,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -116214,7 +116214,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [886 0 R 888 0 R 889 0 R 891 0 R 892 0 R 893 0 R 895 0 R 896 0 R]
@@ -116543,7 +116543,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [901 0 R 902 0 R 903 0 R 904 0 R]
@@ -116554,7 +116554,7 @@ endobj
 endobj
 900 0 obj
 << /Limits [(dfs.datanode.failed.volumes.tolerated) (dm.column.metadata)]
-/Names [(dfs.datanode.failed.volumes.tolerated) 557 0 R (dfs.datanode.max.transfer.threads) 160 0 R (dfs.domain.socket.path) 447 0 R (dialog) 3846 0 R (direct.memory) 1672 0 R (disable-nagle-for-rpc) 1166 0 R (disable.splitting) 568 0 R (disabling-metrics) 3225 0 R (disabling.blockcache) 580 0 R (discovering.available.metrics) 3226 0 R (distributed) 176 0 R (distributed.log.replay.failure.reasons) 1745 0 R (distributed.log.splitting) 1733 0 R (dm.column.metadata) 959 0 R]
+/Names [(dfs.datanode.failed.volumes.tolerated) 557 0 R (dfs.datanode.max.transfer.threads) 160 0 R (dfs.domain.socket.path) 447 0 R (dialog) 3859 0 R (direct.memory) 1672 0 R (disable-nagle-for-rpc) 1166 0 R (disable.splitting) 568 0 R (disabling-metrics) 3225 0 R (disabling.blockcache) 580 0 R (discovering.available.metrics) 3226 0 R (distributed) 176 0 R (distributed.log.replay.failure.reasons) 1745 0 R (distributed.log.splitting) 1733 0 R (dm.column.metadata) 959 0 R]
 >>
 endobj
 901 0 obj
@@ -117563,7 +117563,7 @@ endobj
 /F7.0 914 0 R
 /F7.1 915 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [909 0 R 910 0 R 913 0 R]
@@ -117574,7 +117574,7 @@ endobj
 endobj
 908 0 obj
 << /Limits [(upgrade2.0.ui.splitmerge.by.row) (using-the-java-api)]
-/Names [(upgrade2.0.ui.splitmerge.by.row) 723 0 R (upgrade2.0.zkconfig) 714 0 R (upgrading) 608 0 R (upgrading-2) 4124 0 R (use-cases-for-observer-coprocessors) 2393 0 R (user-interface) 1979 0 R (using-existing-zookeeper-ensemble) 3999 0 R (using-hbase-shell) 2431 0 R (using-rest-endpoints) 2228 0 R (using-secure-http-https-for-the-web-ui) 1296 0 R (using-the-code-rolling-restart-sh-code-script) 3207 0 R (using-the-java-api) 2432 0 R]
+/Names [(upgrade2.0.ui.splitmerge.by.row) 723 0 R (upgrade2.0.zkconfig) 714 0 R (upgrading) 608 0 R (upgrading-2) 4137 0 R (use-cases-for-observer-coprocessors) 2393 0 R (user-interface) 1979 0 R (using-existing-zookeeper-ensemble) 4012 0 R (using-hbase-shell) 2431 0 R (using-rest-endpoints) 2228 0 R (using-secure-http-https-for-the-web-ui) 1296 0 R (using-the-code-rolling-restart-sh-code-script) 3207 0 R (using-the-java-api) 2432 0 R]
 >>
 endobj
 909 0 obj
@@ -117604,7 +117604,7 @@ endobj
 endobj
 912 0 obj
 << /Limits [(rowcounter) (save-the-dataframe)]
-/Names [(rowcounter) 3148 0 R (rowcounter-example) 1241 0 R (rowkey.design) 1002 0 R (rowkey.regionsplits) 1043 0 R (rowkey.scope) 1040 0 R (rpc) 4367 0 R (rpc.configs) 4386 0 R (rpc.logging) 2742 0 R (rpcscheduler-dispatch-callrunner-p1-abstract-void-1) 4424 0 R (rs.failover.details) 3308 0 R (rs_metrics) 3234 0 R (rsgroup) 3457 0 R (run-canary-test-as-a-daemon) 3065 0 R (run.insitu) 3766 0 R (running-canary-in-a-kerberos-enabled-cluster) 3071 0 R (running-multiple-workloads-on-a-single-cluster) 3322 0 R (running-the-shell-in-non-interactive-mode) 804 0 R (save-the-dataframe) 2351 0 R]
+/Names [(rowcounter) 3148 0 R (rowcounter-example) 1241 0 R (rowkey.design) 1002 0 R (rowkey.regionsplits) 1043 0 R (rowkey.scope) 1040 0 R (rpc) 4380 0 R (rpc.configs) 4399 0 R (rpc.logging) 2742 0 R (rpcscheduler-dispatch-callrunner-p1-abstract-void-1) 4437 0 R (rs.failover.details) 3321 0 R (rs_metrics) 3234 0 R (rsgroup) 3471 0 R (run-canary-test-as-a-daemon) 3065 0 R (run.insitu) 3779 0 R (running-canary-in-a-kerberos-enabled-cluster) 3071 0 R (running-multiple-workloads-on-a-single-cluster) 3335 0 R (running-the-shell-in-non-interactive-mode) 804 0 R (save-the-dataframe) 2351 0 R]
 >>
 endobj
 913 0 obj
@@ -117622,22 +117622,22 @@ endobj
 << /Type /Font
 /BaseFont /0c7a4a+mplus-1p-regular
 /Subtype /TrueType
-/FontDescriptor 5295 0 R
+/FontDescriptor 5308 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5297 0 R
-/ToUnicode 5296 0 R
+/Widths 5310 0 R
+/ToUnicode 5309 0 R
 >>
 endobj
 915 0 obj
 << /Type /Font
 /BaseFont /a99fc7+mplus-1p-regular
 /Subtype /TrueType
-/FontDescriptor 5299 0 R
+/FontDescriptor 5312 0 R
 /FirstChar 32
 /LastChar 255
-/Widths 5301 0 R
-/ToUnicode 5300 0 R
+/Widths 5314 0 R
+/ToUnicode 5313 0 R
 >>
 endobj
 916 0 obj
@@ -119505,7 +119505,7 @@ endobj
 /F7.1 915 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [918 0 R 919 0 R 922 0 R 923 0 R 924 0 R 925 0 R]
@@ -123441,7 +123441,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -124423,7 +124423,7 @@ endobj
 /F1.1 40 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [936 0 R 937 0 R 938 0 R 939 0 R 940 0 R 941 0 R]
@@ -125315,7 +125315,7 @@ endobj
 /F2.0 31 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [945 0 R 946 0 R 948 0 R 949 0 R 951 0 R 953 0 R]
@@ -125480,7 +125480,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -125647,7 +125647,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [960 0 R]
@@ -125876,7 +125876,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -125994,7 +125994,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [967 0 R 968 0 R]
@@ -126407,7 +126407,7 @@ endobj
 /F1.0 10 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [972 0 R 973 0 R 974 0 R 975 0 R 976 0 R 977 0 R]
@@ -127882,7 +127882,7 @@ endobj
 /F4.0 37 0 R
 /F5.1 47 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [981 0 R 982 0 R 983 0 R 985 0 R]
@@ -128402,7 +128402,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [990 0 R]
@@ -128624,7 +128624,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [994 0 R]
@@ -128941,7 +128941,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [998 0 R]
@@ -129357,7 +129357,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -130086,7 +130086,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -131019,7 +131019,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1008 0 R 1009 0 R 1010 0 R 1011 0 R 1013 0 R 1014 0 R 1015 0 R 1016 0 R 1017 0 R 1019 0 R 1020 0 R]
@@ -131644,7 +131644,7 @@ endobj
 /F2.0 31 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1023 0 R 1024 0 R 1025 0 R 1027 0 R 1029 0 R]
@@ -135225,7 +135225,7 @@ endobj
 /F5.1 47 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1035 0 R 1036 0 R]
@@ -135943,7 +135943,7 @@ endobj
 /F2.0 31 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1039 0 R]
@@ -135965,7 +135965,7 @@ endobj
 endobj
 1042 0 obj
 << /Limits [(cf.in.memory) (class-coprocessorrpcchannel-1)]
-/Names [(cf.in.memory) 2582 0 R (cf.keep.deleted) 1075 0 R (changes-of-note) 669 0 R (changing.compression) 4217 0 R (changing.rowkeys) 1041 0 R (chaos.monkey.properties) 3726 0 R (checking-for-success-or-failure-in-scripts) 812 0 R (choosing-region-servers-to-replicate-to) 3301 0 R (class-class-locktimeoutexception-1) 4472 0 R (class-coprocessorhost-e) 4399 0 R (class-coprocessorrpcchannel-1) 4396 0 R]
+/Names [(cf.in.memory) 2582 0 R (cf.keep.deleted) 1075 0 R (changes-of-note) 669 0 R (changing.compression) 4230 0 R (changing.rowkeys) 1041 0 R (chaos.monkey.properties) 3739 0 R (checking-for-success-or-failure-in-scripts) 812 0 R (choosing-region-servers-to-replicate-to) 3314 0 R (class-class-locktimeoutexception-1) 4485 0 R (class-coprocessorhost-e) 4412 0 R (class-coprocessorrpcchannel-1) 4409 0 R]
 >>
 endobj
 1043 0 obj
@@ -139720,7 +139720,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1046 0 R]
@@ -140193,7 +140193,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1051 0 R 1052 0 R 1054 0 R]
@@ -140573,7 +140573,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1058 0 R 1059 0 R 1060 0 R 1062 0 R]
@@ -140714,7 +140714,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1067 0 R]
@@ -140725,7 +140725,7 @@ endobj
 endobj
 1066 0 obj
 << /Limits [(schema.versions) (sect.zookeeper.session.timeout)]
-/Names [(schema.versions) 1049 0 R (schema.versions.max) 1050 0 R (scopes) 4159 0 R (scripting) 801 0 R (secondary-replica-failover) 1967 0 R (secondary.indexes) 1086 0 R (secondary.indexes.coproc) 1100 0 R (secondary.indexes.dualwrite) 1096 0 R (secondary.indexes.filter) 1090 0 R (secondary.indexes.periodic) 1092 0 R (secondary.indexes.summary) 1098 0 R (sect.zookeeper.session.timeout) 551 0 R]
+/Names [(schema.versions) 1049 0 R (schema.versions.max) 1050 0 R (scopes) 4172 0 R (scripting) 801 0 R (secondary-replica-failover) 1967 0 R (secondary.indexes) 1086 0 R (secondary.indexes.coproc) 1100 0 R (secondary.indexes.dualwrite) 1096 0 R (secondary.indexes.filter) 1090 0 R (secondary.indexes.periodic) 1092 0 R (secondary.indexes.summary) 1098 0 R (sect.zookeeper.session.timeout) 551 0 R]
 >>
 endobj
 1067 0 obj
@@ -141151,7 +141151,7 @@ endobj
 /F3.0 35 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1071 0 R 1072 0 R]
@@ -141842,7 +141842,7 @@ endobj
 /F7.0 914 0 R
 /F7.1 915 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1076 0 R 1077 0 R]
@@ -147557,7 +147557,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -153503,7 +153503,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -154589,7 +154589,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -155275,7 +155275,7 @@ endobj
 /F1.0 10 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1087 0 R 1088 0 R 1089 0 R 1091 0 R 1093 0 R]
@@ -155580,7 +155580,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1097 0 R 1099 0 R 1101 0 R]
@@ -155788,7 +155788,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1105 0 R]
@@ -156584,7 +156584,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1109 0 R 1112 0 R]
@@ -157562,7 +157562,7 @@ endobj
 /F5.1 47 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1117 0 R 1118 0 R]
@@ -158242,7 +158242,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1122 0 R 1124 0 R 1125 0 R 1126 0 R]
@@ -158995,7 +158995,7 @@ endobj
 /F3.0 35 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1130 0 R]
@@ -159631,7 +159631,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1137 0 R]
@@ -160435,7 +160435,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1141 0 R]
@@ -160998,7 +160998,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1146 0 R]
@@ -162557,7 +162557,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1153 0 R]
@@ -163301,7 +163301,7 @@ endobj
 /F2.0 31 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1157 0 R 1158 0 R 1159 0 R]
@@ -163469,7 +163469,7 @@ endobj
 /Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
 /Font << /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -164615,7 +164615,7 @@ endobj
 /F4.0 37 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -165893,7 +165893,7 @@ endobj
 /F2.0 31 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1171 0 R 1172 0 R 1173 0 R 1174 0 R 1175 0 R]
@@ -166642,7 +166642,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -166658,7 +166658,7 @@ endobj
 endobj
 1181 0 obj
 << /Limits [(others) (perf.general)]
-/Names [(others) 2359 0 R (output) 3251 0 R (package) 3553 0 R (page-allocation-failure) 2988 0 R (passing-vm-options-to-the-shell) 820 0 R (passwordless.ssh.quickstart) 89 0 R (perf.99th.percentile) 2517 0 R (perf.batch.loading) 2600 0 R (perf.casestudy) 2720 0 R (perf.compactions.and.splits) 2518 0 R (perf.compression) 2585 0 R (perf.compression.however) 2588 0 R (perf.configurations) 2515 0 R (perf.deleting) 2679 0 R (perf.deleting.queue) 2680 0 R (perf.deleting.rpc) 2684 0 R (perf.ec2) 2712 0 R (perf.general) 2595 0 R]
+/Names [(others) 2359 0 R (output) 3251 0 R (package) 3566 0 R (page-allocation-failure) 2988 0 R (passing-vm-options-to-the-shell) 820 0 R (passwordless.ssh.quickstart) 89 0 R (perf.99th.percentile) 2517 0 R (perf.batch.loading) 2600 0 R (perf.casestudy) 2720 0 R (perf.compactions.and.splits) 2518 0 R (perf.compression) 2585 0 R (perf.compression.however) 2588 0 R (perf.configurations) 2515 0 R (perf.deleting) 2679 0 R (perf.deleting.queue) 2680 0 R (perf.deleting.rpc) 2684 0 R (perf.ec2) 2712 0 R (perf.general) 2595 0 R]
 >>
 endobj
 1182 0 obj
@@ -167493,7 +167493,7 @@ endobj
 /F1.1 40 0 R
 /F7.0 914 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1188 0 R]
@@ -168041,7 +168041,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1194 0 R 1195 0 R 1196 0 R 1197 0 R 1198 0 R 1199 0 R]
@@ -168052,12 +168052,12 @@ endobj
 endobj
 1192 0 obj
 << /Limits [(keysize.cf) (load-the-dataframe)]
-/Names [(keysize.cf) 1026 0 R (keysize.patterns) 1031 0 R (keysize.row) 1030 0 R (keyvalue) 1830 0 R (keyvalue.example) 1831 0 R (known-incompatibilities-among-hbase-versions) 4389 0 R (language-integrated-query) 2357 0 R (lb) 3198 0 R (life-of-a-wal-edit) 3291 0 R (limit-server-failure-impact) 1167 0 R (list-of-major-changes-for-hbase-2-0) 4393 0 R (load-the-dataframe) 2354 0 R]
+/Names [(keysize.cf) 1026 0 R (keysize.patterns) 1031 0 R (keysize.row) 1030 0 R (keyvalue) 1830 0 R (keyvalue.example) 1831 0 R (known-incompatibilities-among-hbase-versions) 4402 0 R (language-integrated-query) 2357 0 R (lb) 3198 0 R (life-of-a-wal-edit) 3304 0 R (limit-server-failure-impact) 1167 0 R (list-of-major-changes-for-hbase-2-0) 4406 0 R (load-the-dataframe) 2354 0 R]
 >>
 endobj
 1193 0 obj
 << /Limits [(multiple-typed-queues) (schema.updates)]
-/Kids [835 0 R 3959 0 R 1904 0 R 3421 0 R 3359 0 R 3043 0 R 1181 0 R 2613 0 R 2649 0 R 2519 0 R 2626 0 R 2478 0 R 366 0 R 3327 0 R 1630 0 R 3027 0 R 3796 0 R 912 0 R 3149 0 R 1136 0 R]
+/Kids [835 0 R 3972 0 R 1904 0 R 3435 0 R 3372 0 R 3043 0 R 1181 0 R 2613 0 R 2649 0 R 2519 0 R 2626 0 R 2478 0 R 366 0 R 3340 0 R 1630 0 R 3027 0 R 3809 0 R 912 0 R 3149 0 R 1136 0 R]
 >>
 endobj
 1194 0 obj
@@ -169131,7 +169131,7 @@ endobj
 /F3.0 35 0 R
 /F1.1 40 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1203 0 R]
@@ -169758,7 +169758,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -170088,7 +170088,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -170841,7 +170841,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1210 0 R 1211 0 R]
@@ -171279,7 +171279,7 @@ endobj
 /Font << /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1214 0 R]
@@ -171807,7 +171807,7 @@ endobj
 /F4.0 37 0 R
 /F3.0 35 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1218 0 R 1219 0 R]
@@ -172121,7 +172121,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -172873,7 +172873,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1226 0 R 1227 0 R 1228 0 R 1229 0 R 1230 0 R 1231 0 R 1232 0 R 1233 0 R 1234 0 R]
@@ -173110,7 +173110,7 @@ endobj
 /Font << /F2.0 31 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1238 0 R]
@@ -173419,7 +173419,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1242 0 R 1243 0 R 1244 0 R]
@@ -173671,7 +173671,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1250 0 R 1252 0 R]
@@ -176227,7 +176227,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 /Annots [1257 0 R]
@@ -178484,7 +178484,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 /Annots [1261 0 R]
@@ -180440,7 +180440,7 @@ endobj
 /F1.0 10 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -184441,7 +184441,7 @@ endobj
 /Font << /F4.0 37 0 R
 /F1.0 10 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -186700,7 +186700,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -190155,7 +190155,7 @@ endobj
 /F1.0 10 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -191762,7 +191762,7 @@ endobj
 /F4.0 37 0 R
 /F2.0 31 0 R
 >>
-/XObject << /Stamp2 5014 0 R
+/XObject << /Stamp2 5027 0 R
 >>
 >>
 >>
@@ -192926,7 +192926,7 @@ endobj
 /F1.0 10 0 R
 /F4.0 37 0 R
 >>
-/XObject << /Stamp1 5013 0 R
+/XObject << /Stamp1 5026 0 R
 >>
 >>
 >>
@@ -193083,7 +193083,7 @@ endobj
 /Font

<TRUNCATED>

[45/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/apidocs/index-all.html
----------------------------------------------------------------------
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index 8dfd629..f93b10c 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -7987,6 +7987,10 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString--">getRegionNameAsString()</a></span> - Method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString(byte[])</a></span> - Static method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString(RegionInfo, byte[])</a></span> - Static method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HRegionInfo.html#getRegionNameAsString--">getRegionNameAsString()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HRegionInfo.html" title="class in org.apache.hadoop.hbase">HRegionInfo</a></dt>
 <dd>
 <div class="block"><span class="deprecatedLabel">Deprecated.</span></div>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/apidocs/org/apache/hadoop/hbase/client/RegionInfo.html
----------------------------------------------------------------------
diff --git a/apidocs/org/apache/hadoop/hbase/client/RegionInfo.html b/apidocs/org/apache/hadoop/hbase/client/RegionInfo.html
index f35e785..4b3225e 100644
--- a/apidocs/org/apache/hadoop/hbase/client/RegionInfo.html
+++ b/apidocs/org/apache/hadoop/hbase/client/RegionInfo.html
@@ -106,7 +106,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Public
-public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.70">RegionInfo</a></pre>
+public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.72">RegionInfo</a></pre>
 <div class="block">Information about a region. A region is a range of keys in the whole keyspace
  of a table, an identifier (a timestamp) for differentiating between subset
  ranges (after region split) and a replicaId for differentiating the instance
@@ -350,7 +350,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.154">getShortNameToLog</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.156">getShortNameToLog</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a short, printable name for this region
@@ -364,7 +364,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionId</h4>
-<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.159">getRegionId</a>()</pre>
+<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.161">getRegionId</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the regionId.</dd>
@@ -377,7 +377,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionName</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.165">getRegionName</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.167">getRegionName</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the regionName as an array of bytes.</dd>
@@ -392,7 +392,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionNameAsString</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.170">getRegionNameAsString</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.172">getRegionNameAsString</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Region name as a String for use in logging, etc.</dd>
@@ -405,7 +405,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedName</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.175">getEncodedName</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.177">getEncodedName</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the encoded region name.</dd>
@@ -418,7 +418,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getEncodedNameAsBytes</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.180">getEncodedNameAsBytes</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.182">getEncodedNameAsBytes</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the encoded region name as an array of bytes.</dd>
@@ -431,7 +431,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartKey</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.185">getStartKey</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.187">getStartKey</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the startKey.</dd>
@@ -444,7 +444,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getEndKey</h4>
-<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.190">getEndKey</a>()</pre>
+<pre>byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.192">getEndKey</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the endKey.</dd>
@@ -457,7 +457,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getTable</h4>
-<pre><a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.195">getTable</a>()</pre>
+<pre><a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.197">getTable</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>current table name of the region</dd>
@@ -470,7 +470,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getReplicaId</h4>
-<pre>int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.200">getReplicaId</a>()</pre>
+<pre>int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.202">getReplicaId</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>returns region replica id</dd>
@@ -483,7 +483,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplit</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.205">isSplit</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.207">isSplit</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if has been split and has daughters.</dd>
@@ -496,7 +496,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>isOffline</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.210">isOffline</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.212">isOffline</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if this region is offline.</dd>
@@ -509,7 +509,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>isSplitParent</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.215">isSplitParent</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.217">isSplitParent</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if this is a split parent region.</dd>
@@ -522,7 +522,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>isMetaRegion</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.220">isMetaRegion</a>()</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.222">isMetaRegion</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>true if this region is a meta region.</dd>
@@ -535,7 +535,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRange</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.231">containsRange</a>(byte[]&nbsp;rangeStartKey,
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.233">containsRange</a>(byte[]&nbsp;rangeStartKey,
                       byte[]&nbsp;rangeEndKey)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -557,7 +557,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>containsRow</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.237">containsRow</a>(byte[]&nbsp;row)</pre>
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.239">containsRow</a>(byte[]&nbsp;row)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>row</code> - </dd>
@@ -572,7 +572,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre>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/client/RegionInfo.html#line.278">getShortNameToLog</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</pre>
+<pre>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/client/RegionInfo.html#line.300">getShortNameToLog</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a String of short, printable names for <code>hris</code>
@@ -586,7 +586,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getShortNameToLog</h4>
-<pre>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/client/RegionInfo.html#line.286">getShortNameToLog</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;ris)</pre>
+<pre>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/client/RegionInfo.html#line.308">getShortNameToLog</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;ris)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>Return a String of short, printable names for <code>hris</code>
@@ -600,7 +600,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartKey</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.322">getStartKey</a>(byte[]&nbsp;regionName)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.344">getStartKey</a>(byte[]&nbsp;regionName)
                    throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Gets the start key from the specified region name.</div>
 <dl>
@@ -619,7 +619,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>areAdjacent</h4>
-<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.410">areAdjacent</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionA,
+<pre>static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.432">areAdjacent</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionA,
                            <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionB)</pre>
 <div class="block">Check whether two regions are adjacent</div>
 <dl>
@@ -637,7 +637,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>toByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.432">toByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</pre>
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.454">toByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
 <dd><code>ri</code> - </dd>
@@ -654,7 +654,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>prettyPrint</h4>
-<pre>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/client/RegionInfo.html#line.443">prettyPrint</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;encodedRegionName)</pre>
+<pre>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/client/RegionInfo.html#line.465">prettyPrint</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;encodedRegionName)</pre>
 <div class="block">Use logging.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -671,7 +671,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.459">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.481">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                long&nbsp;regionid,
                                boolean&nbsp;newFormat)</pre>
@@ -694,7 +694,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.473">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.495">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                <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;id,
                                boolean&nbsp;newFormat)</pre>
@@ -717,7 +717,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.488">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.510">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                long&nbsp;regionid,
                                int&nbsp;replicaId,
@@ -742,7 +742,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.503">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.525">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                byte[]&nbsp;id,
                                boolean&nbsp;newFormat)</pre>
@@ -765,7 +765,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createRegionName</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.517">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.539">createRegionName</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                                byte[]&nbsp;startKey,
                                byte[]&nbsp;id,
                                int&nbsp;replicaId,
@@ -789,7 +789,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>createMobRegionInfo</h4>
-<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.584">createMobRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
+<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.606">createMobRegionInfo</a>(<a href="../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
 <div class="block">Creates a RegionInfo object for MOB data.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -805,7 +805,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>parseRegionName</h4>
-<pre>static&nbsp;byte[][]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.595">parseRegionName</a>(byte[]&nbsp;regionName)
+<pre>static&nbsp;byte[][]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.617">parseRegionName</a>(byte[]&nbsp;regionName)
                          throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Separate elements of a regionName.</div>
 <dl>
@@ -824,7 +824,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>toDelimitedByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.674">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.696">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Serializes given RegionInfo's as a byte array. Use this instead of
  <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when
@@ -847,7 +847,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>toDelimitedByteArray</h4>
-<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.698">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)
+<pre>static&nbsp;byte[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.720">toDelimitedByteArray</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Use this instead of <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when writing to a stream and you want to use
  the pb mergeDelimitedFrom (w/o the delimiter, pb reads to EOF which may not be what you want).</div>
@@ -867,7 +867,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockList">
 <li class="blockList">
 <h4>parseFrom</h4>
-<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.710">parseFrom</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html?is-external=true" title="class or interface in java.io">DataInputStream</a>&nbsp;in)
+<pre>static&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.732">parseFrom</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html?is-external=true" title="class or interface in java.io">DataInputStream</a>&nbsp;in)
                      throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Parses an RegionInfo instance from the passed in stream.
  Presumes the RegionInfo was serialized to the stream with
@@ -888,7 +888,7 @@ public interface <a href="../../../../../src-html/org/apache/hadoop/hbase/client
 <ul class="blockListLast">
 <li class="blockList">
 <h4>parseDelimitedFrom</h4>
-<pre>static&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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.738">parseDelimitedFrom</a>(byte[]&nbsp;bytes,
+<pre>static&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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/client/RegionInfo.html#line.760">parseDelimitedFrom</a>(byte[]&nbsp;bytes,
                                            int&nbsp;offset,
                                            int&nbsp;length)
                                     throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/apidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
----------------------------------------------------------------------
diff --git a/apidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html b/apidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
index 121acc0..a9a6001 100644
--- a/apidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
+++ b/apidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
@@ -271,29 +271,34 @@
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
-<td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
+                     byte[]&nbsp;regionName)</code>&nbsp;</td>
 </tr>
 <tr class="altColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">AsyncTable.CoprocessorCallback.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html#onRegionComplete-org.apache.hadoop.hbase.client.RegionInfo-R-">onRegionComplete</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                 <a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html" title="type parameter in AsyncTable.CoprocessorCallback">R</a>&nbsp;resp)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">AsyncTable.CoprocessorCallback.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html#onRegionError-org.apache.hadoop.hbase.client.RegionInfo-java.lang.Throwable-">onRegionError</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
              <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</a>&nbsp;error)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)</code>
 <div class="block">Serializes given RegionInfo's as a byte array.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>
 <div class="block">Use this instead of <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when writing to a stream and you want to use


[07/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 647f762..057d9b4 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -702,9 +702,9 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestAtomicOperation.TestStep.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestAtomicOperation.TestStep</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DataBlockEncodingTool.Manipulation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DataBlockEncodingTool.Manipulation</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DataBlockEncodingTool.Manipulation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DataBlockEncodingTool.Manipulation</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
index 79489dc..20ee998 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.748">TestReplicationSourceManager.DummyNodeFailoverWorker</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.764">TestReplicationSourceManager.DummyNodeFailoverWorker</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html?is-external=true" title="class or interface in java.lang">Thread</a></pre>
 </li>
 </ul>
@@ -256,7 +256,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>logZnodesMap</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/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.749">logZnodesMap</a></pre>
+<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/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.765">logZnodesMap</a></pre>
 </li>
 </ul>
 <a name="server">
@@ -265,7 +265,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>server</h4>
-<pre>org.apache.hadoop.hbase.Server <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.750">server</a></pre>
+<pre>org.apache.hadoop.hbase.Server <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.766">server</a></pre>
 </li>
 </ul>
 <a name="deadRS">
@@ -274,7 +274,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>deadRS</h4>
-<pre>private&nbsp;org.apache.hadoop.hbase.ServerName <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.751">deadRS</a></pre>
+<pre>private&nbsp;org.apache.hadoop.hbase.ServerName <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.767">deadRS</a></pre>
 </li>
 </ul>
 <a name="rq">
@@ -283,7 +283,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>rq</h4>
-<pre>org.apache.hadoop.hbase.replication.ReplicationQueueStorage <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.752">rq</a></pre>
+<pre>org.apache.hadoop.hbase.replication.ReplicationQueueStorage <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.768">rq</a></pre>
 </li>
 </ul>
 </li>
@@ -300,7 +300,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DummyNodeFailoverWorker</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.754">DummyNodeFailoverWorker</a>(org.apache.hadoop.hbase.ServerName&nbsp;deadRS,
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.770">DummyNodeFailoverWorker</a>(org.apache.hadoop.hbase.ServerName&nbsp;deadRS,
                                org.apache.hadoop.hbase.Server&nbsp;s)
                         throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
@@ -323,7 +323,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>run</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.762">run</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.778">run</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html?is-external=true#run--" title="class or interface in java.lang">run</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</a></code></dd>
@@ -338,7 +338,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>isLogZnodesMapPopulated</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.784">isLogZnodesMapPopulated</a>()</pre>
+<pre>private&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html#line.800">isLogZnodesMapPopulated</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>1 when the map is not empty.</dd>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
index 0aaa7ef..2057e56 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
@@ -117,7 +117,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.814">TestReplicationSourceManager.DummyServer</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.830">TestReplicationSourceManager.DummyServer</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>
 implements org.apache.hadoop.hbase.Server</pre>
 </li>
@@ -266,7 +266,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>hostname</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.815">hostname</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.831">hostname</a></pre>
 </li>
 </ul>
 </li>
@@ -283,7 +283,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>DummyServer</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.817">DummyServer</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.833">DummyServer</a>()</pre>
 </li>
 </ul>
 <a name="DummyServer-java.lang.String-">
@@ -292,7 +292,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DummyServer</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.821">DummyServer</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;hostname)</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.837">DummyServer</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;hostname)</pre>
 </li>
 </ul>
 </li>
@@ -309,7 +309,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getConfiguration</h4>
-<pre>public&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.826">getConfiguration</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.842">getConfiguration</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getConfiguration</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -322,7 +322,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getZooKeeper</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.zookeeper.ZKWatcher&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.831">getZooKeeper</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.zookeeper.ZKWatcher&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.847">getZooKeeper</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getZooKeeper</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -335,7 +335,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getCoordinatedStateManager</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.CoordinatedStateManager&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.836">getCoordinatedStateManager</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.CoordinatedStateManager&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.852">getCoordinatedStateManager</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getCoordinatedStateManager</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -348,7 +348,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getConnection</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.client.ClusterConnection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.840">getConnection</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.client.ClusterConnection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.856">getConnection</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getConnection</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -361,7 +361,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getMetaTableLocator</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.zookeeper.MetaTableLocator&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.845">getMetaTableLocator</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.zookeeper.MetaTableLocator&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.861">getMetaTableLocator</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getMetaTableLocator</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -374,7 +374,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getServerName</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.ServerName&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.850">getServerName</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.ServerName&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.866">getServerName</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getServerName</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -387,7 +387,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>abort</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.855">abort</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;why,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.871">abort</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;why,
                   <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</a>&nbsp;e)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
@@ -401,7 +401,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>isAborted</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.860">isAborted</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.876">isAborted</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>isAborted</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Abortable</code></dd>
@@ -414,7 +414,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>stop</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.865">stop</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;why)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.881">stop</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;why)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>stop</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Stoppable</code></dd>
@@ -427,7 +427,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>isStopped</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.870">isStopped</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.886">isStopped</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>isStopped</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Stoppable</code></dd>
@@ -440,7 +440,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getChoreService</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.ChoreService&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.875">getChoreService</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.ChoreService&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.891">getChoreService</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getChoreService</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -453,7 +453,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getClusterConnection</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.client.ClusterConnection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.880">getClusterConnection</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.client.ClusterConnection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.896">getClusterConnection</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getClusterConnection</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -466,7 +466,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>getFileSystem</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.886">getFileSystem</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.902">getFileSystem</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>getFileSystem</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -479,7 +479,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockList">
 <li class="blockList">
 <h4>isStopping</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.891">isStopping</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.907">isStopping</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>isStopping</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.hbase.Server</code></dd>
@@ -492,7 +492,7 @@ implements org.apache.hadoop.hbase.Server</pre>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>createConnection</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.client.Connection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.896">createConnection</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
+<pre>public&nbsp;org.apache.hadoop.hbase.client.Connection&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html#line.912">createConnection</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
                                                            throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
index 72f1f8b..6d35eb1 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.803">TestReplicationSourceManager.FailInitializeDummyReplicationSource</a>
+<pre>static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.819">TestReplicationSourceManager.FailInitializeDummyReplicationSource</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationSourceDummy.html" title="class in org.apache.hadoop.hbase.replication">ReplicationSourceDummy</a></pre>
 </li>
 </ul>
@@ -214,7 +214,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/replication/Replicati
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FailInitializeDummyReplicationSource</h4>
-<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html#line.803">FailInitializeDummyReplicationSource</a>()</pre>
+<pre><a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html#line.819">FailInitializeDummyReplicationSource</a>()</pre>
 </li>
 </ul>
 </li>
@@ -231,7 +231,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/replication/Replicati
 <ul class="blockListLast">
 <li class="blockList">
 <h4>init</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html#line.806">init</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html#line.822">init</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                  org.apache.hadoop.fs.FileSystem&nbsp;fs,
                  org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager&nbsp;manager,
                  org.apache.hadoop.hbase.replication.ReplicationQueueStorage&nbsp;rq,

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
index 1f83ea8..f7b65cf 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":10,"i1":10,"i2":10,"i3":9,"i4":9,"i5":9,"i6":10,"i7":10,"i8":10,"i9":9,"i10":10,"i11":9,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":9};
+var methods = {"i0":10,"i1":10,"i2":10,"i3":9,"i4":9,"i5":9,"i6":10,"i7":10,"i8":10,"i9":9,"i10":10,"i11":9,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":9};
 var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -393,6 +393,10 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testRemoveRemoteWALs--">testRemoveRemoteWALs</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i22" class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testSameWALPrefix--">testSameWALPrefix</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i23" class="rowColor">
 <td class="colFirst"><code>private static void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#waitPeer-java.lang.String-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager-boolean-">waitPeer</a></span>(<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;peerId,
         org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager&nbsp;manager,
@@ -922,13 +926,27 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="testSameWALPrefix--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testSameWALPrefix</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.650">testSameWALPrefix</a>()
+                       throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
+<dl>
+<dt><span class="throwsLabel">Throws:</span></dt>
+<dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></code></dd>
+</dl>
+</li>
+</ul>
 <a name="addPeerAndWait-java.lang.String-org.apache.hadoop.hbase.replication.ReplicationPeerConfig-boolean-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>addPeerAndWait</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.653">addPeerAndWait</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;peerId,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.669">addPeerAndWait</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;peerId,
                             org.apache.hadoop.hbase.replication.ReplicationPeerConfig&nbsp;peerConfig,
                             boolean&nbsp;waitForSource)
                      throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
@@ -947,7 +965,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>waitPeer</h4>
-<pre>private static&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.669">waitPeer</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;peerId,
+<pre>private static&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.685">waitPeer</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;peerId,
                              org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager&nbsp;manager,
                              boolean&nbsp;waitForSource)</pre>
 </li>
@@ -958,7 +976,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removePeerAndWait</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.693">removePeerAndWait</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;peerId)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.709">removePeerAndWait</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;peerId)
                         throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <div class="block">Remove a peer and wait for it to get cleaned up</div>
 <dl>
@@ -975,7 +993,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getBulkLoadWALEdit</h4>
-<pre>private&nbsp;org.apache.hadoop.hbase.wal.WALEdit&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.713">getBulkLoadWALEdit</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/NavigableMap.html?is-external=true" title="class or interface in java.util">NavigableMap</a>&lt;byte[],<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;scope)</pre>
+<pre>private&nbsp;org.apache.hadoop.hbase.wal.WALEdit&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#line.729">getBulkLoadWALEdit</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/NavigableMap.html?is-external=true" title="class or interface in java.util">NavigableMap</a>&lt;byte[],<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;scope)</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManagerZkImpl.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManagerZkImpl.html b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManagerZkImpl.html
index e91098c..87c6341 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManagerZkImpl.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManagerZkImpl.html
@@ -209,7 +209,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/replication/regionser
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html" title="class in org.apache.hadoop.hbase.replication.regionserver">TestReplicationSourceManager</a></h3>
-<code><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#setUp--">setUp</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#setupZkAndReplication--">setupZkAndReplication</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#tearDown--">tearDown</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#tearDownAfterClass--">tearDownAfterClass</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testBulkLoadWALEdits--">testBulkLoadWALEdits</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testBulkLoadWALEditsWithoutBulkLoadReplicationEnabled--">testBulkLoadWALEditsWithoutBulkLoadReplicationEnabled</a>, <a href="../../../../
 ../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testClaimQueues--">testClaimQueues</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCleanupFailoverQueues--">testCleanupFailoverQueues</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCleanupUnknownPeerZNode--">testCleanupUnknownPeerZNode</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCompactionWALEdits--">testCompactionWALEdits</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testLogRoll--">testLogRoll</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testPeerRemovalCleanup--">testPeerRemovalCleanup</a>, <a href="../../../../../../org/apache/hadoop/hbase/rep
 lication/regionserver/TestReplicationSourceManager.html#testRemovePeerMetricsCleanup--">testRemovePeerMetricsCleanup</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testRemoveRemoteWALs--">testRemoveRemoteWALs</a></code></li>
+<code><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#setUp--">setUp</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#setupZkAndReplication--">setupZkAndReplication</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#tearDown--">tearDown</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#tearDownAfterClass--">tearDownAfterClass</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testBulkLoadWALEdits--">testBulkLoadWALEdits</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testBulkLoadWALEditsWithoutBulkLoadReplicationEnabled--">testBulkLoadWALEditsWithoutBulkLoadReplicationEnabled</a>, <a href="../../../../
 ../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testClaimQueues--">testClaimQueues</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCleanupFailoverQueues--">testCleanupFailoverQueues</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCleanupUnknownPeerZNode--">testCleanupUnknownPeerZNode</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testCompactionWALEdits--">testCompactionWALEdits</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testLogRoll--">testLogRoll</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testPeerRemovalCleanup--">testPeerRemovalCleanup</a>, <a href="../../../../../../org/apache/hadoop/hbase/rep
 lication/regionserver/TestReplicationSourceManager.html#testRemovePeerMetricsCleanup--">testRemovePeerMetricsCleanup</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testRemoveRemoteWALs--">testRemoveRemoteWALs</a>, <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testSameWALPrefix--">testSameWALPrefix</a></code></li>
 </ul>
 <ul class="blockList">
 <li class="blockList"><a name="methods.inherited.from.class.java.lang.Object">

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
index b21ae88..9e0700e 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
@@ -141,9 +141,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/TestWALSplit.Corruptions.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">TestWALSplit.Corruptions</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal.html
index 6801190..c61b254 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal.html
@@ -97,7 +97,7 @@
 <span class="sourceLineNo">089</span>      when(rl.getWriteRequestCount()).thenReturn(0L);<a name="line.89"></a>
 <span class="sourceLineNo">090</span>      when(rl.getMemStoreSize()).thenReturn(Size.ZERO);<a name="line.90"></a>
 <span class="sourceLineNo">091</span>      when(rl.getStoreFileSize()).thenReturn(Size.ZERO);<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      regionLoadMap.put(info.getEncodedNameAsBytes(), rl);<a name="line.92"></a>
+<span class="sourceLineNo">092</span>      regionLoadMap.put(info.getRegionName(), rl);<a name="line.92"></a>
 <span class="sourceLineNo">093</span>    }<a name="line.93"></a>
 <span class="sourceLineNo">094</span>    when(serverMetrics.getRegionMetrics()).thenReturn(regionLoadMap);<a name="line.94"></a>
 <span class="sourceLineNo">095</span>    return serverMetrics;<a name="line.95"></a>


[13/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        break;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      }<a name="line.433"></a>
+<span 

<TRUNCATED>

[18/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<

<TRUNCATED>

[06/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
index 13b918c..fe1ee7f 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
@@ -139,7 +139,7 @@
 <span class="sourceLineNo">131</span>      when(rl.getWriteRequestCount()).thenReturn(0L);<a name="line.131"></a>
 <span class="sourceLineNo">132</span>      when(rl.getMemStoreSize()).thenReturn(Size.ZERO);<a name="line.132"></a>
 <span class="sourceLineNo">133</span>      when(rl.getStoreFileSize()).thenReturn(Size.ZERO);<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      regionLoadMap.put(info.getEncodedNameAsBytes(), rl);<a name="line.134"></a>
+<span class="sourceLineNo">134</span>      regionLoadMap.put(info.getRegionName(), rl);<a name="line.134"></a>
 <span class="sourceLineNo">135</span>    }<a name="line.135"></a>
 <span class="sourceLineNo">136</span>    when(serverMetrics.getRegionMetrics()).thenReturn(regionLoadMap);<a name="line.136"></a>
 <span class="sourceLineNo">137</span>    return serverMetrics;<a name="line.137"></a>
@@ -230,273 +230,275 @@
 <span class="sourceLineNo">222</span><a name="line.222"></a>
 <span class="sourceLineNo">223</span>      loadBalancer.setClusterMetrics(clusterStatus);<a name="line.223"></a>
 <span class="sourceLineNo">224</span>    }<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    assertTrue(loadBalancer.loads.get(REGION_KEY) != null);<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    assertTrue(loadBalancer.loads.get(REGION_KEY).size() == 15);<a name="line.226"></a>
-<span class="sourceLineNo">227</span><a name="line.227"></a>
-<span class="sourceLineNo">228</span>    Queue&lt;BalancerRegionLoad&gt; loads = loadBalancer.loads.get(REGION_KEY);<a name="line.228"></a>
-<span class="sourceLineNo">229</span>    int i = 0;<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    while(loads.size() &gt; 0) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>      BalancerRegionLoad rl = loads.remove();<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      assertEquals(i + (numClusterStatusToAdd - 15), rl.getStorefileSizeMB());<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      i ++;<a name="line.233"></a>
-<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
-<span class="sourceLineNo">235</span>  }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>  @Test<a name="line.237"></a>
-<span class="sourceLineNo">238</span>  public void testNeedBalance() {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);<a name="line.239"></a>
-<span class="sourceLineNo">240</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);<a name="line.240"></a>
-<span class="sourceLineNo">241</span>    loadBalancer.setConf(conf);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; servers = mockClusterServers(mockCluster);<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(servers);<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      assertNull(plans);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    // reset config<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);<a name="line.248"></a>
-<span class="sourceLineNo">249</span>    loadBalancer.setConf(conf);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>  }<a name="line.250"></a>
-<span class="sourceLineNo">251</span><a name="line.251"></a>
-<span class="sourceLineNo">252</span>  @Test<a name="line.252"></a>
-<span class="sourceLineNo">253</span>  public void testLocalityCost() throws Exception {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    Configuration conf = HBaseConfiguration.create();<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    MockNoopMasterServices master = new MockNoopMasterServices();<a name="line.255"></a>
-<span class="sourceLineNo">256</span>    StochasticLoadBalancer.CostFunction<a name="line.256"></a>
-<span class="sourceLineNo">257</span>        costFunction = new ServerLocalityCostFunction(conf, master);<a name="line.257"></a>
-<span class="sourceLineNo">258</span><a name="line.258"></a>
-<span class="sourceLineNo">259</span>    for (int test = 0; test &lt; clusterRegionLocationMocks.length; test++) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      int[][] clusterRegionLocations = clusterRegionLocationMocks[test];<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      MockCluster cluster = new MockCluster(clusterRegionLocations);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      costFunction.init(cluster);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      double cost = costFunction.cost();<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      double expected = 1 - expectedLocalities[test];<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      assertEquals(expected, cost, 0.001);<a name="line.265"></a>
-<span class="sourceLineNo">266</span>    }<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  }<a name="line.267"></a>
-<span class="sourceLineNo">268</span><a name="line.268"></a>
-<span class="sourceLineNo">269</span>  @Test<a name="line.269"></a>
-<span class="sourceLineNo">270</span>  public void testMoveCost() throws Exception {<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    Configuration conf = HBaseConfiguration.create();<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    StochasticLoadBalancer.CostFunction<a name="line.272"></a>
-<span class="sourceLineNo">273</span>        costFunction = new StochasticLoadBalancer.MoveCostFunction(conf);<a name="line.273"></a>
-<span class="sourceLineNo">274</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      costFunction.init(cluster);<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      double cost = costFunction.cost();<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      assertEquals(0.0f, cost, 0.001);<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>      // cluster region number is smaller than maxMoves=600<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      cluster.setNumRegions(200);<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      cluster.setNumMovedRegions(10);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      cost = costFunction.cost();<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      assertEquals(0.05f, cost, 0.001);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>      cluster.setNumMovedRegions(100);<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      cost = costFunction.cost();<a name="line.286"></a>
-<span class="sourceLineNo">287</span>      assertEquals(0.5f, cost, 0.001);<a name="line.287"></a>
-<span class="sourceLineNo">288</span>      cluster.setNumMovedRegions(200);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>      cost = costFunction.cost();<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      assertEquals(1.0f, cost, 0.001);<a name="line.290"></a>
-<span class="sourceLineNo">291</span><a name="line.291"></a>
-<span class="sourceLineNo">292</span><a name="line.292"></a>
-<span class="sourceLineNo">293</span>      // cluster region number is bigger than maxMoves=2500<a name="line.293"></a>
-<span class="sourceLineNo">294</span>      cluster.setNumRegions(10000);<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      cluster.setNumMovedRegions(250);<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      cost = costFunction.cost();<a name="line.296"></a>
-<span class="sourceLineNo">297</span>      assertEquals(0.1f, cost, 0.001);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>      cluster.setNumMovedRegions(1250);<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      cost = costFunction.cost();<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      assertEquals(0.5f, cost, 0.001);<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      cluster.setNumMovedRegions(2500);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      cost = costFunction.cost();<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      assertEquals(1.0f, cost, 0.01);<a name="line.303"></a>
-<span class="sourceLineNo">304</span>    }<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  @Test<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  public void testSkewCost() {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    Configuration conf = HBaseConfiguration.create();<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    StochasticLoadBalancer.CostFunction<a name="line.310"></a>
-<span class="sourceLineNo">311</span>        costFunction = new StochasticLoadBalancer.RegionCountSkewCostFunction(conf);<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      costFunction.init(mockCluster(mockCluster));<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      double cost = costFunction.cost();<a name="line.314"></a>
-<span class="sourceLineNo">315</span>      assertTrue(cost &gt;= 0);<a name="line.315"></a>
-<span class="sourceLineNo">316</span>      assertTrue(cost &lt;= 1.01);<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    }<a name="line.317"></a>
-<span class="sourceLineNo">318</span><a name="line.318"></a>
-<span class="sourceLineNo">319</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    assertEquals(0,costFunction.cost(), 0.01);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 1, 1}));<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    costFunction.init(mockCluster(new int[]{0, 0, 1, 1, 1}));<a name="line.323"></a>
+<span class="sourceLineNo">225</span><a name="line.225"></a>
+<span class="sourceLineNo">226</span>    String regionNameAsString = RegionInfo.getRegionNameAsString(Bytes.toBytes(REGION_KEY));<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    assertTrue(loadBalancer.loads.get(regionNameAsString) != null);<a name="line.227"></a>
+<span class="sourceLineNo">228</span>    assertTrue(loadBalancer.loads.get(regionNameAsString).size() == 15);<a name="line.228"></a>
+<span class="sourceLineNo">229</span><a name="line.229"></a>
+<span class="sourceLineNo">230</span>    Queue&lt;BalancerRegionLoad&gt; loads = loadBalancer.loads.get(regionNameAsString);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    int i = 0;<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    while(loads.size() &gt; 0) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      BalancerRegionLoad rl = loads.remove();<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      assertEquals(i + (numClusterStatusToAdd - 15), rl.getStorefileSizeMB());<a name="line.234"></a>
+<span class="sourceLineNo">235</span>      i ++;<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    }<a name="line.236"></a>
+<span class="sourceLineNo">237</span>  }<a name="line.237"></a>
+<span class="sourceLineNo">238</span><a name="line.238"></a>
+<span class="sourceLineNo">239</span>  @Test<a name="line.239"></a>
+<span class="sourceLineNo">240</span>  public void testNeedBalance() {<a name="line.240"></a>
+<span class="sourceLineNo">241</span>    float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);<a name="line.241"></a>
+<span class="sourceLineNo">242</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    loadBalancer.setConf(conf);<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; servers = mockClusterServers(mockCluster);<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(servers);<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      assertNull(plans);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    }<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    // reset config<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    loadBalancer.setConf(conf);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>  }<a name="line.252"></a>
+<span class="sourceLineNo">253</span><a name="line.253"></a>
+<span class="sourceLineNo">254</span>  @Test<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  public void testLocalityCost() throws Exception {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    Configuration conf = HBaseConfiguration.create();<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    MockNoopMasterServices master = new MockNoopMasterServices();<a name="line.257"></a>
+<span class="sourceLineNo">258</span>    StochasticLoadBalancer.CostFunction<a name="line.258"></a>
+<span class="sourceLineNo">259</span>        costFunction = new ServerLocalityCostFunction(conf, master);<a name="line.259"></a>
+<span class="sourceLineNo">260</span><a name="line.260"></a>
+<span class="sourceLineNo">261</span>    for (int test = 0; test &lt; clusterRegionLocationMocks.length; test++) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      int[][] clusterRegionLocations = clusterRegionLocationMocks[test];<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      MockCluster cluster = new MockCluster(clusterRegionLocations);<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      costFunction.init(cluster);<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      double cost = costFunction.cost();<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      double expected = 1 - expectedLocalities[test];<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      assertEquals(expected, cost, 0.001);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    }<a name="line.268"></a>
+<span class="sourceLineNo">269</span>  }<a name="line.269"></a>
+<span class="sourceLineNo">270</span><a name="line.270"></a>
+<span class="sourceLineNo">271</span>  @Test<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  public void testMoveCost() throws Exception {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>    Configuration conf = HBaseConfiguration.create();<a name="line.273"></a>
+<span class="sourceLineNo">274</span>    StochasticLoadBalancer.CostFunction<a name="line.274"></a>
+<span class="sourceLineNo">275</span>        costFunction = new StochasticLoadBalancer.MoveCostFunction(conf);<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      costFunction.init(cluster);<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      double cost = costFunction.cost();<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      assertEquals(0.0f, cost, 0.001);<a name="line.280"></a>
+<span class="sourceLineNo">281</span><a name="line.281"></a>
+<span class="sourceLineNo">282</span>      // cluster region number is smaller than maxMoves=600<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      cluster.setNumRegions(200);<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      cluster.setNumMovedRegions(10);<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      cost = costFunction.cost();<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      assertEquals(0.05f, cost, 0.001);<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      cluster.setNumMovedRegions(100);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      cost = costFunction.cost();<a name="line.288"></a>
+<span class="sourceLineNo">289</span>      assertEquals(0.5f, cost, 0.001);<a name="line.289"></a>
+<span class="sourceLineNo">290</span>      cluster.setNumMovedRegions(200);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      cost = costFunction.cost();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      assertEquals(1.0f, cost, 0.001);<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span><a name="line.294"></a>
+<span class="sourceLineNo">295</span>      // cluster region number is bigger than maxMoves=2500<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      cluster.setNumRegions(10000);<a name="line.296"></a>
+<span class="sourceLineNo">297</span>      cluster.setNumMovedRegions(250);<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      cost = costFunction.cost();<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      assertEquals(0.1f, cost, 0.001);<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      cluster.setNumMovedRegions(1250);<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      cost = costFunction.cost();<a name="line.301"></a>
+<span class="sourceLineNo">302</span>      assertEquals(0.5f, cost, 0.001);<a name="line.302"></a>
+<span class="sourceLineNo">303</span>      cluster.setNumMovedRegions(2500);<a name="line.303"></a>
+<span class="sourceLineNo">304</span>      cost = costFunction.cost();<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      assertEquals(1.0f, cost, 0.01);<a name="line.305"></a>
+<span class="sourceLineNo">306</span>    }<a name="line.306"></a>
+<span class="sourceLineNo">307</span>  }<a name="line.307"></a>
+<span class="sourceLineNo">308</span><a name="line.308"></a>
+<span class="sourceLineNo">309</span>  @Test<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  public void testSkewCost() {<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    Configuration conf = HBaseConfiguration.create();<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    StochasticLoadBalancer.CostFunction<a name="line.312"></a>
+<span class="sourceLineNo">313</span>        costFunction = new StochasticLoadBalancer.RegionCountSkewCostFunction(conf);<a name="line.313"></a>
+<span class="sourceLineNo">314</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.314"></a>
+<span class="sourceLineNo">315</span>      costFunction.init(mockCluster(mockCluster));<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      double cost = costFunction.cost();<a name="line.316"></a>
+<span class="sourceLineNo">317</span>      assertTrue(cost &gt;= 0);<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      assertTrue(cost &lt;= 1.01);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span><a name="line.320"></a>
+<span class="sourceLineNo">321</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    assertEquals(0,costFunction.cost(), 0.01);<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 1, 1}));<a name="line.323"></a>
 <span class="sourceLineNo">324</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    costFunction.init(mockCluster(new int[]{0, 1, 1, 1, 1}));<a name="line.325"></a>
+<span class="sourceLineNo">325</span>    costFunction.init(mockCluster(new int[]{0, 0, 1, 1, 1}));<a name="line.325"></a>
 <span class="sourceLineNo">326</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    costFunction.init(mockCluster(new int[]{1, 1, 1, 1, 1}));<a name="line.327"></a>
+<span class="sourceLineNo">327</span>    costFunction.init(mockCluster(new int[]{0, 1, 1, 1, 1}));<a name="line.327"></a>
 <span class="sourceLineNo">328</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    costFunction.init(mockCluster(new int[]{10000, 0, 0, 0, 0}));<a name="line.329"></a>
-<span class="sourceLineNo">330</span>    assertEquals(1, costFunction.cost(), 0.01);<a name="line.330"></a>
-<span class="sourceLineNo">331</span>  }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Test<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public void testCostAfterUndoAction() {<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    final int runs = 10;<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    loadBalancer.setConf(conf);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      loadBalancer.initCosts(cluster);<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      for (int i = 0; i != runs; ++i) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        final double expectedCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        Cluster.Action action = loadBalancer.nextAction(cluster);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        cluster.doAction(action);<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        loadBalancer.updateCostsWithAction(cluster, action);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        Cluster.Action undoAction = action.undoAction();<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        cluster.doAction(undoAction);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadBalancer.updateCostsWithAction(cluster, undoAction);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        final double actualCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>        assertEquals(expectedCost, actualCost, 0);<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    }<a name="line.351"></a>
-<span class="sourceLineNo">352</span>  }<a name="line.352"></a>
-<span class="sourceLineNo">353</span><a name="line.353"></a>
-<span class="sourceLineNo">354</span>  @Test<a name="line.354"></a>
-<span class="sourceLineNo">355</span>  public void testTableSkewCost() {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    Configuration conf = HBaseConfiguration.create();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    StochasticLoadBalancer.CostFunction<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        costFunction = new StochasticLoadBalancer.TableSkewCostFunction(conf);<a name="line.358"></a>
-<span class="sourceLineNo">359</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      costFunction.init(cluster);<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      double cost = costFunction.cost();<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      assertTrue(cost &gt;= 0);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      assertTrue(cost &lt;= 1.01);<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><a name="line.367"></a>
-<span class="sourceLineNo">368</span>  @Test<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  public void testRegionLoadCost() {<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    List&lt;BalancerRegionLoad&gt; regionLoads = new ArrayList&lt;&gt;();<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    for (int i = 1; i &lt; 5; i++) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      BalancerRegionLoad regionLoad = mock(BalancerRegionLoad.class);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>      when(regionLoad.getReadRequestsCount()).thenReturn(new Long(i));<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      when(regionLoad.getCpRequestsCount()).thenReturn(new Long(i));<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      when(regionLoad.getStorefileSizeMB()).thenReturn(i);<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      regionLoads.add(regionLoad);<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    }<a name="line.377"></a>
-<span class="sourceLineNo">378</span><a name="line.378"></a>
-<span class="sourceLineNo">379</span>    Configuration conf = HBaseConfiguration.create();<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    StochasticLoadBalancer.ReadRequestCostFunction readCostFunction =<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        new StochasticLoadBalancer.ReadRequestCostFunction(conf);<a name="line.381"></a>
-<span class="sourceLineNo">382</span>    double rateResult = readCostFunction.getRegionLoadCost(regionLoads);<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    // read requests are treated as a rate so the average rate here is simply 1<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    assertEquals(1, rateResult, 0.01);<a name="line.384"></a>
-<span class="sourceLineNo">385</span><a name="line.385"></a>
-<span class="sourceLineNo">386</span>    StochasticLoadBalancer.CPRequestCostFunction cpCostFunction =<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        new StochasticLoadBalancer.CPRequestCostFunction(conf);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    rateResult = cpCostFunction.getRegionLoadCost(regionLoads);<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // coprocessor requests are treated as a rate so the average rate here is simply 1<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    assertEquals(1, rateResult, 0.01);<a name="line.390"></a>
-<span class="sourceLineNo">391</span><a name="line.391"></a>
-<span class="sourceLineNo">392</span>    StochasticLoadBalancer.StoreFileCostFunction storeFileCostFunction =<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        new StochasticLoadBalancer.StoreFileCostFunction(conf);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    double result = storeFileCostFunction.getRegionLoadCost(regionLoads);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    // storefile size cost is simply an average of it's value over time<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    assertEquals(2.5, result, 0.01);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>  }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>  @Test<a name="line.399"></a>
-<span class="sourceLineNo">400</span>  public void testCostFromArray() {<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    Configuration conf = HBaseConfiguration.create();<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    StochasticLoadBalancer.CostFromRegionLoadFunction<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        costFunction = new StochasticLoadBalancer.MemStoreSizeCostFunction(conf);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.404"></a>
-<span class="sourceLineNo">405</span><a name="line.405"></a>
-<span class="sourceLineNo">406</span>    double[] statOne = new double[100];<a name="line.406"></a>
-<span class="sourceLineNo">407</span>    for (int i =0; i &lt; 100; i++) {<a name="line.407"></a>
-<span class="sourceLineNo">408</span>      statOne[i] = 10;<a name="line.408"></a>
-<span class="sourceLineNo">409</span>    }<a name="line.409"></a>
-<span class="sourceLineNo">410</span>    assertEquals(0, costFunction.costFromArray(statOne), 0.01);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>    double[] statTwo= new double[101];<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    for (int i =0; i &lt; 100; i++) {<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      statTwo[i] = 0;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    statTwo[100] = 100;<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    assertEquals(1, costFunction.costFromArray(statTwo), 0.01);<a name="line.417"></a>
-<span class="sourceLineNo">418</span><a name="line.418"></a>
-<span class="sourceLineNo">419</span>    double[] statThree = new double[200];<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    for (int i =0; i &lt; 100; i++) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>      statThree[i] = (0);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      statThree[i+100] = 100;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>    assertEquals(0.5, costFunction.costFromArray(statThree), 0.01);<a name="line.424"></a>
-<span class="sourceLineNo">425</span>  }<a name="line.425"></a>
-<span class="sourceLineNo">426</span><a name="line.426"></a>
-<span class="sourceLineNo">427</span>  @Test<a name="line.427"></a>
-<span class="sourceLineNo">428</span>  public void testLosingRs() throws Exception {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    int numNodes = 3;<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    int numRegions = 20;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    int numRegionsPerServer = 3; //all servers except one<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    int replication = 1;<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    int numTables = 2;<a name="line.433"></a>
-<span class="sourceLineNo">434</span><a name="line.434"></a>
-<span class="sourceLineNo">435</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.435"></a>
-<span class="sourceLineNo">436</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    List&lt;ServerAndLoad&gt; list = convertToList(serverMap);<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>    List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(serverMap);<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    assertNotNull(plans);<a name="line.441"></a>
-<span class="sourceLineNo">442</span><a name="line.442"></a>
-<span class="sourceLineNo">443</span>    // Apply the plan to the mock cluster.<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    List&lt;ServerAndLoad&gt; balancedCluster = reconcile(list, plans, serverMap);<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    assertClusterAsBalanced(balancedCluster);<a name="line.446"></a>
+<span class="sourceLineNo">329</span>    costFunction.init(mockCluster(new int[]{1, 1, 1, 1, 1}));<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.330"></a>
+<span class="sourceLineNo">331</span>    costFunction.init(mockCluster(new int[]{10000, 0, 0, 0, 0}));<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    assertEquals(1, costFunction.cost(), 0.01);<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  }<a name="line.333"></a>
+<span class="sourceLineNo">334</span><a name="line.334"></a>
+<span class="sourceLineNo">335</span>  @Test<a name="line.335"></a>
+<span class="sourceLineNo">336</span>  public void testCostAfterUndoAction() {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    final int runs = 10;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    loadBalancer.setConf(conf);<a name="line.338"></a>
+<span class="sourceLineNo">339</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      loadBalancer.initCosts(cluster);<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      for (int i = 0; i != runs; ++i) {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        final double expectedCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        Cluster.Action action = loadBalancer.nextAction(cluster);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        cluster.doAction(action);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>        loadBalancer.updateCostsWithAction(cluster, action);<a name="line.346"></a>
+<span class="sourceLineNo">347</span>        Cluster.Action undoAction = action.undoAction();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>        cluster.doAction(undoAction);<a name="line.348"></a>
+<span class="sourceLineNo">349</span>        loadBalancer.updateCostsWithAction(cluster, undoAction);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        final double actualCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        assertEquals(expectedCost, actualCost, 0);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      }<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    }<a name="line.353"></a>
+<span class="sourceLineNo">354</span>  }<a name="line.354"></a>
+<span class="sourceLineNo">355</span><a name="line.355"></a>
+<span class="sourceLineNo">356</span>  @Test<a name="line.356"></a>
+<span class="sourceLineNo">357</span>  public void testTableSkewCost() {<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    Configuration conf = HBaseConfiguration.create();<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    StochasticLoadBalancer.CostFunction<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        costFunction = new StochasticLoadBalancer.TableSkewCostFunction(conf);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      costFunction.init(cluster);<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      double cost = costFunction.cost();<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      assertTrue(cost &gt;= 0);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      assertTrue(cost &lt;= 1.01);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    }<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
+<span class="sourceLineNo">369</span><a name="line.369"></a>
+<span class="sourceLineNo">370</span>  @Test<a name="line.370"></a>
+<span class="sourceLineNo">371</span>  public void testRegionLoadCost() {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    List&lt;BalancerRegionLoad&gt; regionLoads = new ArrayList&lt;&gt;();<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 1; i &lt; 5; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      BalancerRegionLoad regionLoad = mock(BalancerRegionLoad.class);<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      when(regionLoad.getReadRequestsCount()).thenReturn(new Long(i));<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      when(regionLoad.getCpRequestsCount()).thenReturn(new Long(i));<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      when(regionLoad.getStorefileSizeMB()).thenReturn(i);<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      regionLoads.add(regionLoad);<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    }<a name="line.379"></a>
+<span class="sourceLineNo">380</span><a name="line.380"></a>
+<span class="sourceLineNo">381</span>    Configuration conf = HBaseConfiguration.create();<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    StochasticLoadBalancer.ReadRequestCostFunction readCostFunction =<a name="line.382"></a>
+<span class="sourceLineNo">383</span>        new StochasticLoadBalancer.ReadRequestCostFunction(conf);<a name="line.383"></a>
+<span class="sourceLineNo">384</span>    double rateResult = readCostFunction.getRegionLoadCost(regionLoads);<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    // read requests are treated as a rate so the average rate here is simply 1<a name="line.385"></a>
+<span class="sourceLineNo">386</span>    assertEquals(1, rateResult, 0.01);<a name="line.386"></a>
+<span class="sourceLineNo">387</span><a name="line.387"></a>
+<span class="sourceLineNo">388</span>    StochasticLoadBalancer.CPRequestCostFunction cpCostFunction =<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        new StochasticLoadBalancer.CPRequestCostFunction(conf);<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    rateResult = cpCostFunction.getRegionLoadCost(regionLoads);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    // coprocessor requests are treated as a rate so the average rate here is simply 1<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    assertEquals(1, rateResult, 0.01);<a name="line.392"></a>
+<span class="sourceLineNo">393</span><a name="line.393"></a>
+<span class="sourceLineNo">394</span>    StochasticLoadBalancer.StoreFileCostFunction storeFileCostFunction =<a name="line.394"></a>
+<span class="sourceLineNo">395</span>        new StochasticLoadBalancer.StoreFileCostFunction(conf);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>    double result = storeFileCostFunction.getRegionLoadCost(regionLoads);<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    // storefile size cost is simply an average of it's value over time<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    assertEquals(2.5, result, 0.01);<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  }<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>  @Test<a name="line.401"></a>
+<span class="sourceLineNo">402</span>  public void testCostFromArray() {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    Configuration conf = HBaseConfiguration.create();<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    StochasticLoadBalancer.CostFromRegionLoadFunction<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        costFunction = new StochasticLoadBalancer.MemStoreSizeCostFunction(conf);<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>    double[] statOne = new double[100];<a name="line.408"></a>
+<span class="sourceLineNo">409</span>    for (int i =0; i &lt; 100; i++) {<a name="line.409"></a>
+<span class="sourceLineNo">410</span>      statOne[i] = 10;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    assertEquals(0, costFunction.costFromArray(statOne), 0.01);<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    double[] statTwo= new double[101];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    for (int i =0; i &lt; 100; i++) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      statTwo[i] = 0;<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    statTwo[100] = 100;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    assertEquals(1, costFunction.costFromArray(statTwo), 0.01);<a name="line.419"></a>
+<span class="sourceLineNo">420</span><a name="line.420"></a>
+<span class="sourceLineNo">421</span>    double[] statThree = new double[200];<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    for (int i =0; i &lt; 100; i++) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>      statThree[i] = (0);<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      statThree[i+100] = 100;<a name="line.424"></a>
+<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
+<span class="sourceLineNo">426</span>    assertEquals(0.5, costFunction.costFromArray(statThree), 0.01);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
+<span class="sourceLineNo">428</span><a name="line.428"></a>
+<span class="sourceLineNo">429</span>  @Test<a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public void testLosingRs() throws Exception {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    int numNodes = 3;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    int numRegions = 20;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>    int numRegionsPerServer = 3; //all servers except one<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    int replication = 1;<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    int numTables = 2;<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>    List&lt;ServerAndLoad&gt; list = convertToList(serverMap);<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>    List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(serverMap);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assertNotNull(plans);<a name="line.443"></a>
+<span class="sourceLineNo">444</span><a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // Apply the plan to the mock cluster.<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    List&lt;ServerAndLoad&gt; balancedCluster = reconcile(list, plans, serverMap);<a name="line.446"></a>
 <span class="sourceLineNo">447</span><a name="line.447"></a>
-<span class="sourceLineNo">448</span>    ServerName sn = serverMap.keySet().toArray(new ServerName[serverMap.size()])[0];<a name="line.448"></a>
+<span class="sourceLineNo">448</span>    assertClusterAsBalanced(balancedCluster);<a name="line.448"></a>
 <span class="sourceLineNo">449</span><a name="line.449"></a>
-<span class="sourceLineNo">450</span>    ServerName deadSn = ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 100);<a name="line.450"></a>
+<span class="sourceLineNo">450</span>    ServerName sn = serverMap.keySet().toArray(new ServerName[serverMap.size()])[0];<a name="line.450"></a>
 <span class="sourceLineNo">451</span><a name="line.451"></a>
-<span class="sourceLineNo">452</span>    serverMap.put(deadSn, new ArrayList&lt;&gt;(0));<a name="line.452"></a>
+<span class="sourceLineNo">452</span>    ServerName deadSn = ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 100);<a name="line.452"></a>
 <span class="sourceLineNo">453</span><a name="line.453"></a>
-<span class="sourceLineNo">454</span>    plans = loadBalancer.balanceCluster(serverMap);<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    assertNull(plans);<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  // This mock allows us to test the LocalityCostFunction<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  private class MockCluster extends BaseLoadBalancer.Cluster {<a name="line.459"></a>
-<span class="sourceLineNo">460</span><a name="line.460"></a>
-<span class="sourceLineNo">461</span>    private int[][] localities = null;   // [region][server] = percent of blocks<a name="line.461"></a>
+<span class="sourceLineNo">454</span>    serverMap.put(deadSn, new ArrayList&lt;&gt;(0));<a name="line.454"></a>
+<span class="sourceLineNo">455</span><a name="line.455"></a>
+<span class="sourceLineNo">456</span>    plans = loadBalancer.balanceCluster(serverMap);<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    assertNull(plans);<a name="line.457"></a>
+<span class="sourceLineNo">458</span>  }<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>  // This mock allows us to test the LocalityCostFunction<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  private class MockCluster extends BaseLoadBalancer.Cluster {<a name="line.461"></a>
 <span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    public MockCluster(int[][] regions) {<a name="line.463"></a>
+<span class="sourceLineNo">463</span>    private int[][] localities = null;   // [region][server] = percent of blocks<a name="line.463"></a>
 <span class="sourceLineNo">464</span><a name="line.464"></a>
-<span class="sourceLineNo">465</span>      // regions[0] is an array where index = serverIndex an value = number of regions<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      super(mockClusterServers(regions[0], 1), null, null, null);<a name="line.466"></a>
-<span class="sourceLineNo">467</span><a name="line.467"></a>
-<span class="sourceLineNo">468</span>      localities = new int[regions.length - 1][];<a name="line.468"></a>
-<span class="sourceLineNo">469</span>      for (int i = 1; i &lt; regions.length; i++) {<a name="line.469"></a>
-<span class="sourceLineNo">470</span>        int regionIndex = i - 1;<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        localities[regionIndex] = new int[regions[i].length - 1];<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        regionIndexToServerIndex[regionIndex] = regions[i][0];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        for (int j = 1; j &lt; regions[i].length; j++) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>          int serverIndex = j - 1;<a name="line.474"></a>
-<span class="sourceLineNo">475</span>          localities[regionIndex][serverIndex] = regions[i][j] &gt; 100 ? regions[i][j] % 100 : regions[i][j];<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        }<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>    @Override<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    float getLocalityOfRegion(int region, int server) {<a name="line.481"></a>
-<span class="sourceLineNo">482</span>      // convert the locality percentage to a fraction<a name="line.482"></a>
-<span class="sourceLineNo">483</span>      return localities[region][server] / 100.0f;<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    }<a name="line.484"></a>
-<span class="sourceLineNo">485</span><a name="line.485"></a>
-<span class="sourceLineNo">486</span>    @Override<a name="line.486"></a>
-<span class="sourceLineNo">487</span>    public int getRegionSizeMB(int region) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      return 1;<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    }<a name="line.489"></a>
-<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>}<a name="line.491"></a>
+<span class="sourceLineNo">465</span>    public MockCluster(int[][] regions) {<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>      // regions[0] is an array where index = serverIndex an value = number of regions<a name="line.467"></a>
+<span class="sourceLineNo">468</span>      super(mockClusterServers(regions[0], 1), null, null, null);<a name="line.468"></a>
+<span class="sourceLineNo">469</span><a name="line.469"></a>
+<span class="sourceLineNo">470</span>      localities = new int[regions.length - 1][];<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      for (int i = 1; i &lt; regions.length; i++) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        int regionIndex = i - 1;<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        localities[regionIndex] = new int[regions[i].length - 1];<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        regionIndexToServerIndex[regionIndex] = regions[i][0];<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        for (int j = 1; j &lt; regions[i].length; j++) {<a name="line.475"></a>
+<span class="sourceLineNo">476</span>          int serverIndex = j - 1;<a name="line.476"></a>
+<span class="sourceLineNo">477</span>          localities[regionIndex][serverIndex] = regions[i][j] &gt; 100 ? regions[i][j] % 100 : regions[i][j];<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>    }<a name="line.480"></a>
+<span class="sourceLineNo">481</span><a name="line.481"></a>
+<span class="sourceLineNo">482</span>    @Override<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    float getLocalityOfRegion(int region, int server) {<a name="line.483"></a>
+<span class="sourceLineNo">484</span>      // convert the locality percentage to a fraction<a name="line.484"></a>
+<span class="sourceLineNo">485</span>      return localities[region][server] / 100.0f;<a name="line.485"></a>
+<span class="sourceLineNo">486</span>    }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>    @Override<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    public int getRegionSizeMB(int region) {<a name="line.489"></a>
+<span class="sourceLineNo">490</span>      return 1;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
+<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
+<span class="sourceLineNo">493</span>}<a name="line.493"></a>
 
 
 


[17/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sou

<TRUNCATED>

[25/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo"

<TRUNCATED>

[31/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LoadCandidateGenerator.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span

<TRUNCATED>

[47/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.


Project: http://git-wip-us.apache.org/repos/asf/hbase-site/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase-site/commit/9592fdb5
Tree: http://git-wip-us.apache.org/repos/asf/hbase-site/tree/9592fdb5
Diff: http://git-wip-us.apache.org/repos/asf/hbase-site/diff/9592fdb5

Branch: refs/heads/asf-site
Commit: 9592fdb5864ff3e5d36dbcf983e9f235f672fd0b
Parents: c21eba9
Author: jenkins <bu...@apache.org>
Authored: Fri Nov 9 14:52:37 2018 +0000
Committer: jenkins <bu...@apache.org>
Committed: Fri Nov 9 14:52:37 2018 +0000

----------------------------------------------------------------------
 acid-semantics.html                             |     4 +-
 apache_hbase_reference_guide.pdf                | 22251 +++++++++--------
 apidocs/index-all.html                          |     4 +
 .../apache/hadoop/hbase/client/RegionInfo.html  |    68 +-
 .../hbase/client/class-use/RegionInfo.html      |    15 +-
 .../apache/hadoop/hbase/client/RegionInfo.html  |  1488 +-
 book.html                                       |    64 +-
 bulk-loads.html                                 |     4 +-
 checkstyle-aggregate.html                       |   158 +-
 checkstyle.rss                                  |     4 +-
 coc.html                                        |     4 +-
 dependencies.html                               |     4 +-
 dependency-convergence.html                     |     4 +-
 dependency-info.html                            |     4 +-
 dependency-management.html                      |     4 +-
 devapidocs/constant-values.html                 |     4 +-
 devapidocs/index-all.html                       |     6 +
 .../org/apache/hadoop/hbase/HRegionInfo.html    |     2 +-
 .../hadoop/hbase/backup/package-tree.html       |     4 +-
 .../hbase/client/ImmutableHRegionInfo.html      |     2 +-
 .../apache/hadoop/hbase/client/RegionInfo.html  |   179 +-
 .../RegionInfoBuilder.MutableRegionInfo.html    |    38 +-
 .../hbase/client/UnmodifyableHRegionInfo.html   |     2 +-
 .../hbase/client/class-use/RegionInfo.html      |    41 +-
 .../hadoop/hbase/client/package-tree.html       |    24 +-
 .../hadoop/hbase/filter/package-tree.html       |    10 +-
 .../hadoop/hbase/io/hfile/package-tree.html     |     6 +-
 .../apache/hadoop/hbase/ipc/package-tree.html   |     2 +-
 .../hadoop/hbase/mapreduce/package-tree.html    |     4 +-
 .../master/balancer/StochasticLoadBalancer.html |    94 +-
 .../hadoop/hbase/master/package-tree.html       |     2 +-
 .../hbase/master/procedure/package-tree.html    |     4 +-
 .../hadoop/hbase/monitoring/package-tree.html   |     2 +-
 .../org/apache/hadoop/hbase/package-tree.html   |    16 +-
 .../hadoop/hbase/quotas/package-tree.html       |     6 +-
 .../hadoop/hbase/regionserver/package-tree.html |    22 +-
 .../regionserver/querymatcher/package-tree.html |     2 +-
 .../regionserver/wal/ProtobufLogReader.html     |     4 +-
 .../hbase/regionserver/wal/package-tree.html    |     2 +-
 .../hadoop/hbase/replication/package-tree.html  |     2 +-
 ...icationSourceManager.NodeFailoverWorker.html |    12 +-
 ...SourceManager.ReplicationQueueOperation.html |     4 +-
 .../regionserver/ReplicationSourceManager.html  |   137 +-
 .../replication/regionserver/package-tree.html  |     2 +-
 .../hadoop/hbase/rest/model/package-tree.html   |     2 +-
 .../hbase/security/access/package-tree.html     |     2 +-
 .../hadoop/hbase/security/package-tree.html     |     2 +-
 .../hadoop/hbase/util/HBaseFsck.MetaEntry.html  |     2 +-
 .../apache/hadoop/hbase/util/package-tree.html  |     8 +-
 .../org/apache/hadoop/hbase/Version.html        |     4 +-
 .../apache/hadoop/hbase/client/RegionInfo.html  |  1488 +-
 .../RegionInfoBuilder.MutableRegionInfo.html    |   338 +-
 .../hadoop/hbase/client/RegionInfoBuilder.html  |   338 +-
 ...asticLoadBalancer.CPRequestCostFunction.html |   976 +-
 ...ochasticLoadBalancer.CandidateGenerator.html |   976 +-
 ...lancer.CostFromRegionLoadAsRateFunction.html |   976 +-
 ...LoadBalancer.CostFromRegionLoadFunction.html |   976 +-
 .../StochasticLoadBalancer.CostFunction.html    |   976 +-
 ...sticLoadBalancer.LoadCandidateGenerator.html |   976 +-
 ...alancer.LocalityBasedCandidateGenerator.html |   976 +-
 ...cLoadBalancer.LocalityBasedCostFunction.html |   976 +-
 ...icLoadBalancer.MemStoreSizeCostFunction.html |   976 +-
 ...StochasticLoadBalancer.MoveCostFunction.html |   976 +-
 ...ncer.PrimaryRegionCountSkewCostFunction.html |   976 +-
 ...icLoadBalancer.RackLocalityCostFunction.html |   976 +-
 ...icLoadBalancer.RandomCandidateGenerator.html |   976 +-
 ...ticLoadBalancer.ReadRequestCostFunction.html |   976 +-
 ...oadBalancer.RegionCountSkewCostFunction.html |   976 +-
 ...alancer.RegionReplicaCandidateGenerator.html |   976 +-
 ...dBalancer.RegionReplicaHostCostFunction.html |   976 +-
 ...cer.RegionReplicaRackCandidateGenerator.html |   976 +-
 ...dBalancer.RegionReplicaRackCostFunction.html |   976 +-
 ...LoadBalancer.ServerLocalityCostFunction.html |   976 +-
 ...asticLoadBalancer.StoreFileCostFunction.html |   976 +-
 ...asticLoadBalancer.TableSkewCostFunction.html |   976 +-
 ...icLoadBalancer.WriteRequestCostFunction.html |   976 +-
 .../master/balancer/StochasticLoadBalancer.html |   976 +-
 .../wal/ProtobufLogReader.WALHdrContext.html    |   234 +-
 .../wal/ProtobufLogReader.WALHdrResult.html     |   234 +-
 .../regionserver/wal/ProtobufLogReader.html     |   234 +-
 ...icationSourceManager.NodeFailoverWorker.html |  1568 +-
 ...SourceManager.ReplicationQueueOperation.html |  1568 +-
 .../regionserver/ReplicationSourceManager.html  |  1568 +-
 .../master/AssignmentManagerStatusTmplImpl.html |     8 +-
 .../hbase/tmpl/master/MasterStatusTmplImpl.html |   314 +-
 downloads.html                                  |     4 +-
 export_control.html                             |     4 +-
 images/1-snapshot.png                           |   Bin 0 -> 125659 bytes
 images/2-snapshots.png                          |   Bin 0 -> 118250 bytes
 images/empty-snapshots.png                      |   Bin 0 -> 94959 bytes
 images/master-snapshot.png                      |   Bin 0 -> 249530 bytes
 index.html                                      |     4 +-
 integration.html                                |     4 +-
 issue-tracking.html                             |     4 +-
 license.html                                    |     4 +-
 mail-lists.html                                 |     4 +-
 metrics.html                                    |     4 +-
 old_news.html                                   |     4 +-
 plugin-management.html                          |     4 +-
 plugins.html                                    |     4 +-
 poweredbyhbase.html                             |     4 +-
 project-info.html                               |     4 +-
 project-reports.html                            |     4 +-
 project-summary.html                            |     4 +-
 pseudo-distributed.html                         |     4 +-
 replication.html                                |     4 +-
 resources.html                                  |     4 +-
 source-repository.html                          |     4 +-
 sponsors.html                                   |     4 +-
 supportingprojects.html                         |     4 +-
 team-list.html                                  |     4 +-
 testdevapidocs/index-all.html                   |     2 +
 .../TestStochasticLoadBalancer.MockCluster.html |    10 +-
 .../balancer/TestStochasticLoadBalancer.html    |    18 +-
 .../org/apache/hadoop/hbase/package-tree.html   |    10 +-
 .../hadoop/hbase/procedure/package-tree.html    |     8 +-
 .../hadoop/hbase/procedure2/package-tree.html   |     2 +-
 .../hadoop/hbase/regionserver/package-tree.html |     2 +-
 ...onSourceManager.DummyNodeFailoverWorker.html |    16 +-
 ...estReplicationSourceManager.DummyServer.html |    38 +-
 ...er.FailInitializeDummyReplicationSource.html |     6 +-
 .../TestReplicationSourceManager.html           |    28 +-
 .../TestReplicationSourceManagerZkImpl.html     |     2 +-
 .../apache/hadoop/hbase/wal/package-tree.html   |     2 +-
 ...cerWithStochasticLoadBalancerAsInternal.html |     2 +-
 .../TestStochasticLoadBalancer.MockCluster.html |   520 +-
 .../balancer/TestStochasticLoadBalancer.html    |   520 +-
 ...onSourceManager.DummyNodeFailoverWorker.html |   498 +-
 ...estReplicationSourceManager.DummyServer.html |   498 +-
 ...er.FailInitializeDummyReplicationSource.html |   498 +-
 .../TestReplicationSourceManager.html           |   498 +-
 131 files changed, 30750 insertions(+), 28567 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/acid-semantics.html
----------------------------------------------------------------------
diff --git a/acid-semantics.html b/acid-semantics.html
index 2412116..92f3d5a 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Apache HBase (TM) ACID Properties
@@ -611,7 +611,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 


[19/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCandidateGenerator.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTim

<TRUNCATED>

[09/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
index 083ab07..be28dfa 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
@@ -31,54 +31,54 @@
 <span class="sourceLineNo">023</span>import java.util.Collection;<a name="line.23"></a>
 <span class="sourceLineNo">024</span>import java.util.Collections;<a name="line.24"></a>
 <span class="sourceLineNo">025</span>import java.util.HashMap;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.HashSet;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.Iterator;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import java.util.List;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import java.util.Map;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import java.util.NavigableSet;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import java.util.Set;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import java.util.SortedSet;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import java.util.TreeSet;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import java.util.UUID;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import java.util.concurrent.ConcurrentMap;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import java.util.concurrent.Future;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import java.util.concurrent.RejectedExecutionException;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import java.util.concurrent.TimeUnit;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import java.util.stream.Collectors;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.conf.Configuration;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.FileSystem;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.fs.Path;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.HConstants;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.Server;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.ServerName;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.TableName;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.63"></a>
-<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.67"></a>
-<span class="sourceLineNo">068</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.68"></a>
-<span class="sourceLineNo">069</span>import org.apache.zookeeper.KeeperException;<a name="line.69"></a>
-<span class="sourceLineNo">070</span>import org.slf4j.Logger;<a name="line.70"></a>
-<span class="sourceLineNo">071</span>import org.slf4j.LoggerFactory;<a name="line.71"></a>
-<span class="sourceLineNo">072</span><a name="line.72"></a>
-<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.73"></a>
+<span class="sourceLineNo">026</span>import java.util.Iterator;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.NavigableSet;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import java.util.Set;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import java.util.SortedSet;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import java.util.TreeSet;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import java.util.UUID;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentMap;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import java.util.concurrent.Future;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import java.util.concurrent.RejectedExecutionException;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import java.util.concurrent.TimeUnit;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import java.util.stream.Collectors;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.conf.Configuration;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.fs.FileSystem;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.Path;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.HConstants;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.Server;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.ServerName;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.TableName;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.64"></a>
+<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.66"></a>
+<span class="sourceLineNo">067</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>import org.apache.zookeeper.KeeperException;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>import org.slf4j.Logger;<a name="line.69"></a>
+<span class="sourceLineNo">070</span>import org.slf4j.LoggerFactory;<a name="line.70"></a>
+<span class="sourceLineNo">071</span><a name="line.71"></a>
+<span class="sourceLineNo">072</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.collect.Sets;<a name="line.73"></a>
 <span class="sourceLineNo">074</span>import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;<a name="line.74"></a>
 <span class="sourceLineNo">075</span><a name="line.75"></a>
 <span class="sourceLineNo">076</span>/**<a name="line.76"></a>
@@ -156,7 +156,7 @@
 <span class="sourceLineNo">148</span>  private final Configuration conf;<a name="line.148"></a>
 <span class="sourceLineNo">149</span>  private final FileSystem fs;<a name="line.149"></a>
 <span class="sourceLineNo">150</span>  // The paths to the latest log of each wal group, for new coming peers<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private final Set&lt;Path&gt; latestPaths;<a name="line.151"></a>
+<span class="sourceLineNo">151</span>  private final Map&lt;String, Path&gt; latestPaths;<a name="line.151"></a>
 <span class="sourceLineNo">152</span>  // Path to the wals directories<a name="line.152"></a>
 <span class="sourceLineNo">153</span>  private final Path logDir;<a name="line.153"></a>
 <span class="sourceLineNo">154</span>  // Path to the wal archive<a name="line.154"></a>
@@ -224,7 +224,7 @@
 <span class="sourceLineNo">216</span>    tfb.setNameFormat("ReplicationExecutor-%d");<a name="line.216"></a>
 <span class="sourceLineNo">217</span>    tfb.setDaemon(true);<a name="line.217"></a>
 <span class="sourceLineNo">218</span>    this.executor.setThreadFactory(tfb.build());<a name="line.218"></a>
-<span class="sourceLineNo">219</span>    this.latestPaths = new HashSet&lt;Path&gt;();<a name="line.219"></a>
+<span class="sourceLineNo">219</span>    this.latestPaths = new HashMap&lt;&gt;();<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    this.replicationForBulkLoadDataEnabled = conf.getBoolean(<a name="line.220"></a>
 <span class="sourceLineNo">221</span>      HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, HConstants.REPLICATION_BULKLOAD_ENABLE_DEFAULT);<a name="line.221"></a>
 <span class="sourceLineNo">222</span>    this.sleepForRetries = this.conf.getLong("replication.source.sync.sleepforretries", 1000);<a name="line.222"></a>
@@ -379,756 +379,754 @@
 <span class="sourceLineNo">371</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByGroup = new HashMap&lt;&gt;();<a name="line.371"></a>
 <span class="sourceLineNo">372</span>      this.walsById.put(peerId, walsByGroup);<a name="line.372"></a>
 <span class="sourceLineNo">373</span>      // Add the latest wal to that source's queue<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      if (this.latestPaths.size() &gt; 0) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        for (Path logPath : latestPaths) {<a name="line.375"></a>
-<span class="sourceLineNo">376</span>          String name = logPath.getName();<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          String walPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(name);<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          NavigableSet&lt;String&gt; logs = new TreeSet&lt;&gt;();<a name="line.378"></a>
-<span class="sourceLineNo">379</span>          logs.add(name);<a name="line.379"></a>
-<span class="sourceLineNo">380</span>          walsByGroup.put(walPrefix, logs);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>          // Abort RS and throw exception to make add peer failed<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          abortAndThrowIOExceptionWhenFail(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, name));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          src.enqueueLog(logPath);<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>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    if (peerConfig.isSyncReplication()) {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    src.startup();<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    return src;<a name="line.393"></a>
-<span class="sourceLineNo">394</span>  }<a name="line.394"></a>
-<span class="sourceLineNo">395</span><a name="line.395"></a>
-<span class="sourceLineNo">396</span>  /**<a name="line.396"></a>
-<span class="sourceLineNo">397</span>   * &lt;p&gt;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.398"></a>
-<span class="sourceLineNo">399</span>   * &lt;/p&gt;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>   * &lt;p&gt;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.403"></a>
-<span class="sourceLineNo">404</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.404"></a>
-<span class="sourceLineNo">405</span>   * &lt;/p&gt;<a name="line.405"></a>
-<span class="sourceLineNo">406</span>   * &lt;p&gt;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>   * See HBASE-20426 for more details.<a name="line.407"></a>
-<span class="sourceLineNo">408</span>   * &lt;/p&gt;<a name="line.408"></a>
-<span class="sourceLineNo">409</span>   * @param peerId the id of the sync replication peer<a name="line.409"></a>
-<span class="sourceLineNo">410</span>   */<a name="line.410"></a>
-<span class="sourceLineNo">411</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    // walsById.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    ReplicationSourceInterface toRemove;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    synchronized (latestPaths) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      toRemove = sources.put(peerId, src);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      if (toRemove != null) {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        toRemove.terminate(terminateMessage);<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        toRemove.getSourceMetrics().clear();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      }<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.429"></a>
-<span class="sourceLineNo">430</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      // from the replication queue storage.<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    src.startup();<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      for (String wal : walsByGroup) {<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<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>    synchronized (walsById) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      wals.forEach((k, v) -&gt; {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        if (walsByGroup != null) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>          walsByGroup.removeAll(v);<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      });<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // simplify the logic.<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    synchronized (this.oldsources) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.455"></a>
-<span class="sourceLineNo">456</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.457"></a>
-<span class="sourceLineNo">458</span>          String queueId = oldSource.getQueueId();<a name="line.458"></a>
-<span class="sourceLineNo">459</span>          oldSource.terminate(terminateMessage);<a name="line.459"></a>
-<span class="sourceLineNo">460</span>          oldSource.getSourceMetrics().clear();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.461"></a>
-<span class="sourceLineNo">462</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.462"></a>
-<span class="sourceLineNo">463</span>          iter.remove();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        }<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /**<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.470"></a>
-<span class="sourceLineNo">471</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.471"></a>
-<span class="sourceLineNo">472</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.472"></a>
-<span class="sourceLineNo">473</span>   * @param peerId the id of the replication peer<a name="line.473"></a>
-<span class="sourceLineNo">474</span>   */<a name="line.474"></a>
-<span class="sourceLineNo">475</span>  public void refreshSources(String peerId) throws IOException {<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    String terminateMessage = "Peer " + peerId +<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    synchronized (this.latestPaths) {<a name="line.481"></a>
-<span class="sourceLineNo">482</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.482"></a>
-<span class="sourceLineNo">483</span>      if (toRemove != null) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        toRemove.terminate(terminateMessage);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      }<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      }<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    src.startup();<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.495"></a>
-<span class="sourceLineNo">496</span>    synchronized (this.oldsources) {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.500"></a>
-<span class="sourceLineNo">501</span>          oldSource.terminate(terminateMessage);<a name="line.501"></a>
-<span class="sourceLineNo">502</span>          this.oldsources.remove(oldSource);<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        }<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      }<a name="line.504"></a>
-<span class="sourceLineNo">505</span>      for (String queueId : previousQueueIds) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.506"></a>
-<span class="sourceLineNo">507</span>        this.oldsources.add(replicationSource);<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        toStartup.add(replicationSource);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>      }<a name="line.512"></a>
-<span class="sourceLineNo">513</span>    }<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      replicationSource.startup();<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
-<span class="sourceLineNo">517</span>  }<a name="line.517"></a>
-<span class="sourceLineNo">518</span><a name="line.518"></a>
-<span class="sourceLineNo">519</span>  /**<a name="line.519"></a>
-<span class="sourceLineNo">520</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.520"></a>
-<span class="sourceLineNo">521</span>   * @param src source to clear<a name="line.521"></a>
-<span class="sourceLineNo">522</span>   */<a name="line.522"></a>
-<span class="sourceLineNo">523</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    if (!this.oldsources.remove(src)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      return false;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    }<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    // Delete queue from storage and memory<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    deleteQueue(src.getQueueId());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    return true;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>  }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    synchronized (oldsources) {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      if (!removeRecoveredSource(src)) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.540"></a>
-<span class="sourceLineNo">541</span>      src.getStats());<a name="line.541"></a>
-<span class="sourceLineNo">542</span>  }<a name="line.542"></a>
-<span class="sourceLineNo">543</span><a name="line.543"></a>
-<span class="sourceLineNo">544</span>  /**<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.545"></a>
-<span class="sourceLineNo">546</span>   * @param src source to clear<a name="line.546"></a>
-<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
-<span class="sourceLineNo">548</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    this.sources.remove(src.getPeerId());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    // Delete queue from storage and memory<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    deleteQueue(src.getQueueId());<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    this.walsById.remove(src.getQueueId());<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  /**<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * Delete a complete queue of wals associated with a replication source<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @param queueId the id of replication queue to delete<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   */<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  private void deleteQueue(String queueId) {<a name="line.561"></a>
-<span class="sourceLineNo">562</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  }<a name="line.563"></a>
-<span class="sourceLineNo">564</span><a name="line.564"></a>
-<span class="sourceLineNo">565</span>  @FunctionalInterface<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  private interface ReplicationQueueOperation {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    void exec() throws ReplicationException;<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>  /**<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.571"></a>
-<span class="sourceLineNo">572</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
-<span class="sourceLineNo">574</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    try {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>      op.exec();<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    } catch (ReplicationException e) {<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.578"></a>
-<span class="sourceLineNo">579</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.579"></a>
-<span class="sourceLineNo">580</span>          .getCause() instanceof InterruptedException) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        throw new RuntimeException(<a name="line.581"></a>
-<span class="sourceLineNo">582</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      }<a name="line.583"></a>
-<span class="sourceLineNo">584</span>      server.abort("Failed to operate on replication queue", e);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    }<a name="line.585"></a>
-<span class="sourceLineNo">586</span>  }<a name="line.586"></a>
-<span class="sourceLineNo">587</span><a name="line.587"></a>
-<span class="sourceLineNo">588</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    try {<a name="line.589"></a>
-<span class="sourceLineNo">590</span>      op.exec();<a name="line.590"></a>
-<span class="sourceLineNo">591</span>    } catch (ReplicationException e) {<a name="line.591"></a>
-<span class="sourceLineNo">592</span>      server.abort("Failed to operate on replication queue", e);<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    }<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>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>    try {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      op.exec();<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    } catch (ReplicationException e) {<a name="line.599"></a>
-<span class="sourceLineNo">600</span>      throw new IOException(e);<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    }<a name="line.601"></a>
-<span class="sourceLineNo">602</span>  }<a name="line.602"></a>
-<span class="sourceLineNo">603</span><a name="line.603"></a>
-<span class="sourceLineNo">604</span>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    try {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      op.exec();<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    } catch (ReplicationException e) {<a name="line.607"></a>
-<span class="sourceLineNo">608</span>      server.abort("Failed to operate on replication queue", e);<a name="line.608"></a>
-<span class="sourceLineNo">609</span>      throw new IOException(e);<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><a name="line.612"></a>
-<span class="sourceLineNo">613</span>  /**<a name="line.613"></a>
-<span class="sourceLineNo">614</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.614"></a>
-<span class="sourceLineNo">615</span>   * replication queue.<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * @param source the replication source<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.617"></a>
-<span class="sourceLineNo">618</span>   */<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.619"></a>
-<span class="sourceLineNo">620</span>      WALEntryBatch entryBatch) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.622"></a>
-<span class="sourceLineNo">623</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.623"></a>
-<span class="sourceLineNo">624</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<a name="line.624"></a>
-<span class="sourceLineNo">625</span>  }<a name="line.625"></a>
-<span class="sourceLineNo">626</span><a name="line.626"></a>
-<span class="sourceLineNo">627</span>  /**<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * file is closed and has no more entries.<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   * @param log Path to the log<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   * @param inclusive whether we should also remove the given log file<a name="line.631"></a>
-<span class="sourceLineNo">632</span>   * @param source the replication source<a name="line.632"></a>
-<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
-<span class="sourceLineNo">634</span>  @VisibleForTesting<a name="line.634"></a>
-<span class="sourceLineNo">635</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    if (source.isRecovered()) {<a name="line.637"></a>
-<span class="sourceLineNo">638</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (wals != null) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.640"></a>
-<span class="sourceLineNo">641</span>        if (walsToRemove.isEmpty()) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>          return;<a name="line.642"></a>
-<span class="sourceLineNo">643</span>        }<a name="line.643"></a>
-<span class="sourceLineNo">644</span>        cleanOldLogs(walsToRemove, source);<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        walsToRemove.clear();<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      }<a name="line.646"></a>
-<span class="sourceLineNo">647</span>    } else {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; wals;<a name="line.648"></a>
-<span class="sourceLineNo">649</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.649"></a>
-<span class="sourceLineNo">650</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      synchronized (this.walsById) {<a name="line.651"></a>
-<span class="sourceLineNo">652</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.652"></a>
-<span class="sourceLineNo">653</span>        if (wals == null) {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>          return;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>        }<a name="line.655"></a>
-<span class="sourceLineNo">656</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>        if (walsToRemove.isEmpty()) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>          return;<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        }<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.660"></a>
-<span class="sourceLineNo">661</span>      }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      // the lock to avoid block preLogRoll<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      cleanOldLogs(walsToRemove, source);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      // now let's remove the files in the set<a name="line.666"></a>
-<span class="sourceLineNo">667</span>      synchronized (this.walsById) {<a name="line.667"></a>
-<span class="sourceLineNo">668</span>        wals.removeAll(walsToRemove);<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      }<a name="line.669"></a>
-<span class="sourceLineNo">670</span>    }<a name="line.670"></a>
-<span class="sourceLineNo">671</span>  }<a name="line.671"></a>
-<span class="sourceLineNo">672</span><a name="line.672"></a>
-<span class="sourceLineNo">673</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      throws IOException {<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    for (String wal : wals) {<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      try {<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.680"></a>
-<span class="sourceLineNo">681</span>          throw new IOException("Can not delete " + walFile);<a name="line.681"></a>
-<span class="sourceLineNo">682</span>        }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>      } catch (FileNotFoundException e) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>        // Just ignore since this means the file has already been deleted.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.686"></a>
-<span class="sourceLineNo">687</span>        // FileSystem.delete, and also catch FNFE.<a name="line.687"></a>
-<span class="sourceLineNo">688</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<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>  }<a name="line.691"></a>
-<span class="sourceLineNo">692</span><a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void cleanOldLogs(NavigableSet&lt;String&gt; wals, ReplicationSourceInterface source) {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    LOG.debug("Removing {} logs in the list: {}", wals.size(), wals);<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    // The intention here is that, we want to delete the remote wal files ASAP as it may effect the<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // failover time if you want to transit the remote cluster from S to A. And the infinite retry<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    // is not a problem, as if we can not contact with the remote HDFS cluster, then usually we can<a name="line.697"></a>
-<span class="sourceLineNo">698</span>    // not contact with the HBase cluster either, so the replication will be blocked either.<a name="line.698"></a>
-<span class="sourceLineNo">699</span>    if (source.isSyncReplication()) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      String peerId = source.getPeerId();<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      String remoteWALDir = source.getPeer().getPeerConfig().getRemoteWALDir();<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      // Filter out the wals need to be removed from the remote directory. Its name should be the<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      // special format, and also, the peer id in its name should match the peer id for the<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      // replication source.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      List&lt;String&gt; remoteWals = wals.stream().filter(w -&gt; SyncReplicationWALProvider<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        .getSyncReplicationPeerIdFromWALName(w).map(peerId::equals).orElse(false))<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        .collect(Collectors.toList());<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.debug("Removing {} logs from remote dir {} in the list: {}", remoteWals.size(),<a name="line.708"></a>
-<span class="sourceLineNo">709</span>        remoteWALDir, remoteWals);<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      if (!remoteWals.isEmpty()) {<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        for (int sleepMultiplier = 0;;) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>          try {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>            removeRemoteWALs(peerId, remoteWALDir, remoteWals);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>            break;<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          } catch (IOException e) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>            LOG.warn("Failed to delete remote wals from remote dir {} for peer {}", remoteWALDir,<a name="line.716"></a>
-<span class="sourceLineNo">717</span>              peerId);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          }<a name="line.718"></a>
-<span class="sourceLineNo">719</span>          if (!source.isSourceActive()) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>            // skip the following operations<a name="line.720"></a>
-<span class="sourceLineNo">721</span>            return;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>          }<a name="line.722"></a>
-<span class="sourceLineNo">723</span>          if (ReplicationUtils.sleepForRetries("Failed to delete remote wals", sleepForRetries,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>            sleepMultiplier, maxRetriesMultiplier)) {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>            sleepMultiplier++;<a name="line.725"></a>
-<span class="sourceLineNo">726</span>          }<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        }<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>    String queueId = source.getQueueId();<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    for (String wal : wals) {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      interruptOrAbortWhenFail(<a name="line.732"></a>
-<span class="sourceLineNo">733</span>        () -&gt; this.queueStorage.removeWAL(server.getServerName(), queueId, wal));<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    }<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  // public because of we call it in TestReplicationEmptyWALRecovery<a name="line.737"></a>
-<span class="sourceLineNo">738</span>  @VisibleForTesting<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  public void preLogRoll(Path newLog) throws IOException {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>    String logName = newLog.getName();<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(logName);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // synchronized on latestPaths to avoid the new open source miss the new log<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    synchronized (this.latestPaths) {<a name="line.743"></a>
-<span class="sourceLineNo">744</span>      // Add log to queue storage<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      for (ReplicationSourceInterface source : this.sources.values()) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>        // If record log to queue storage failed, abort RS and throw exception to make log roll<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        // failed<a name="line.747"></a>
-<span class="sourceLineNo">748</span>        abortAndThrowIOExceptionWhenFail(<a name="line.748"></a>
-<span class="sourceLineNo">749</span>          () -&gt; this.queueStorage.addWAL(server.getServerName(), source.getQueueId(), logName));<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
-<span class="sourceLineNo">751</span><a name="line.751"></a>
-<span class="sourceLineNo">752</span>      // synchronized on walsById to avoid race with cleanOldLogs<a name="line.752"></a>
-<span class="sourceLineNo">753</span>      synchronized (this.walsById) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>        // Update walsById map<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        for (Map.Entry&lt;String, Map&lt;String, NavigableSet&lt;String&gt;&gt;&gt; entry : this.walsById<a name="line.755"></a>
-<span class="sourceLineNo">756</span>          .entrySet()) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>          String peerId = entry.getKey();<a name="line.757"></a>
-<span class="sourceLineNo">758</span>          Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByPrefix = entry.getValue();<a name="line.758"></a>
-<span class="sourceLineNo">759</span>          boolean existingPrefix = false;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>          for (Map.Entry&lt;String, NavigableSet&lt;String&gt;&gt; walsEntry : walsByPrefix.entrySet()) {<a name="line.760"></a>
-<span class="sourceLineNo">761</span>            SortedSet&lt;String&gt; wals = walsEntry.getValue();<a name="line.761"></a>
-<span class="sourceLineNo">762</span>            if (this.sources.isEmpty()) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>              // If there's no slaves, don't need to keep the old wals since<a name="line.763"></a>
-<span class="sourceLineNo">764</span>              // we only consider the last one when a new slave comes in<a name="line.764"></a>
-<span class="sourceLineNo">765</span>              wals.clear();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>            }<a name="line.766"></a>
-<span class="sourceLineNo">767</span>            if (logPrefix.equals(walsEntry.getKey())) {<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              wals.add(logName);<a name="line.768"></a>
-<span class="sourceLineNo">769</span>              existingPrefix = true;<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            }<a name="line.770"></a>
-<span class="sourceLineNo">771</span>          }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>          if (!existingPrefix) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>            // The new log belongs to a new group, add it into this peer<a name="line.773"></a>
-<span class="sourceLineNo">774</span>            LOG.debug("Start tracking logs for wal group {} for peer {}", logPrefix, peerId);<a name="line.774"></a>
-<span class="sourceLineNo">775</span>            NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.775"></a>
-<span class="sourceLineNo">776</span>            wals.add(logName);<a name="line.776"></a>
-<span class="sourceLineNo">777</span>            walsByPrefix.put(logPrefix, wals);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>          }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>        }<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      }<a name="line.780"></a>
-<span class="sourceLineNo">781</span><a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Add to latestPaths<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      Iterator&lt;Path&gt; iterator = latestPaths.iterator();<a name="line.783"></a>
-<span class="sourceLineNo">784</span>      while (iterator.hasNext()) {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        Path path = iterator.next();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>        if (path.getName().contains(logPrefix)) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>          iterator.remove();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>          break;<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        }<a name="line.789"></a>
-<span class="sourceLineNo">790</span>      }<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      this.latestPaths.add(newLog);<a name="line.791"></a>
+<span class="sourceLineNo">374</span>      if (!latestPaths.isEmpty()) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        for (Map.Entry&lt;String, Path&gt; walPrefixAndPath : latestPaths.entrySet()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          Path walPath = walPrefixAndPath.getValue();<a name="line.376"></a>
+<span class="sourceLineNo">377</span>          NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.377"></a>
+<span class="sourceLineNo">378</span>          wals.add(walPath.getName());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          walsByGroup.put(walPrefixAndPath.getKey(), wals);<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          // Abort RS and throw exception to make add peer failed<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          abortAndThrowIOExceptionWhenFail(<a name="line.381"></a>
+<span class="sourceLineNo">382</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, walPath.getName()));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          src.enqueueLog(walPath);<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        }<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>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.387"></a>
+<span class="sourceLineNo">388</span>    if (peerConfig.isSyncReplication()) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    src.startup();<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    return src;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  }<a name="line.393"></a>
+<span class="sourceLineNo">394</span><a name="line.394"></a>
+<span class="sourceLineNo">395</span>  /**<a name="line.395"></a>
+<span class="sourceLineNo">396</span>   * &lt;p&gt;<a name="line.396"></a>
+<span class="sourceLineNo">397</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>   * &lt;/p&gt;<a name="line.398"></a>
+<span class="sourceLineNo">399</span>   * &lt;p&gt;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.400"></a>
+<span class="sourceLineNo">401</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * &lt;/p&gt;<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   * &lt;p&gt;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * See HBASE-20426 for more details.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   * &lt;/p&gt;<a name="line.407"></a>
+<span class="sourceLineNo">408</span>   * @param peerId the id of the sync replication peer<a name="line.408"></a>
+<span class="sourceLineNo">409</span>   */<a name="line.409"></a>
+<span class="sourceLineNo">410</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    // walsById.<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    ReplicationSourceInterface toRemove;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    synchronized (latestPaths) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      toRemove = sources.put(peerId, src);<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      if (toRemove != null) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        toRemove.terminate(terminateMessage);<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        toRemove.getSourceMetrics().clear();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      }<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.429"></a>
+<span class="sourceLineNo">430</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      // from the replication queue storage.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    src.startup();<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.436"></a>
+<span class="sourceLineNo">437</span>      for (String wal : walsByGroup) {<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    synchronized (walsById) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>      wals.forEach((k, v) -&gt; {<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>        if (walsByGroup != null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>          walsByGroup.removeAll(v);<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      });<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // simplify the logic.<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    synchronized (this.oldsources) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.454"></a>
+<span class="sourceLineNo">455</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.455"></a>
+<span class="sourceLineNo">456</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>          String queueId = oldSource.getQueueId();<a name="line.457"></a>
+<span class="sourceLineNo">458</span>          oldSource.terminate(terminateMessage);<a name="line.458"></a>
+<span class="sourceLineNo">459</span>          oldSource.getSourceMetrics().clear();<a name="line.459"></a>
+<span class="sourceLineNo">460</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.460"></a>
+<span class="sourceLineNo">461</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.461"></a>
+<span class="sourceLineNo">462</span>          iter.remove();<a name="line.462"></a>
+<span class="sourceLineNo">463</span>        }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.471"></a>
+<span class="sourceLineNo">472</span>   * @param peerId the id of the replication peer<a name="line.472"></a>
+<span class="sourceLineNo">473</span>   */<a name="line.473"></a>
+<span class="sourceLineNo">474</span>  public void refreshSources(String peerId) throws IOException {<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    String terminateMessage = "Peer " + peerId +<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.478"></a>
+<span class="sourceLineNo">479</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    synchronized (this.latestPaths) {<a name="line.480"></a>
+<span class="sourceLineNo">481</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.481"></a>
+<span class="sourceLineNo">482</span>      if (toRemove != null) {<a name="line.482"></a>
+<span class="sourceLineNo">483</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.483"></a>
+<span class="sourceLineNo">484</span>        toRemove.terminate(terminateMessage);<a name="line.484"></a>
+<span class="sourceLineNo">485</span>      }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.487"></a>
+<span class="sourceLineNo">488</span>      }<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    }<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    src.startup();<a name="line.491"></a>
+<span class="sourceLineNo">492</span><a name="line.492"></a>
+<span class="sourceLineNo">493</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.493"></a>
+<span class="sourceLineNo">494</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.494"></a>
+<span class="sourceLineNo">495</span>    synchronized (this.oldsources) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.496"></a>
+<span class="sourceLineNo">497</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.499"></a>
+<span class="sourceLineNo">500</span>          oldSource.terminate(terminateMessage);<a name="line.500"></a>
+<span class="sourceLineNo">501</span>          this.oldsources.remove(oldSource);<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>      for (String queueId : previousQueueIds) {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.505"></a>
+<span class="sourceLineNo">506</span>        this.oldsources.add(replicationSource);<a name="line.506"></a>
+<span class="sourceLineNo">507</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.507"></a>
+<span class="sourceLineNo">508</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
+<span class="sourceLineNo">510</span>        toStartup.add(replicationSource);<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      }<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      replicationSource.startup();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
+<span class="sourceLineNo">516</span>  }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>  /**<a name="line.518"></a>
+<span class="sourceLineNo">519</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.519"></a>
+<span class="sourceLineNo">520</span>   * @param src source to clear<a name="line.520"></a>
+<span class="sourceLineNo">521</span>   */<a name="line.521"></a>
+<span class="sourceLineNo">522</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    if (!this.oldsources.remove(src)) {<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      return false;<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    // Delete queue from storage and memory<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    deleteQueue(src.getQueueId());<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    return true;<a name="line.530"></a>
+<span class="sourceLineNo">531</span>  }<a name="line.531"></a>
+<span class="sourceLineNo">532</span><a name="line.532"></a>
+<span class="sourceLineNo">533</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.533"></a>
+<span class="sourceLineNo">534</span>    synchronized (oldsources) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      if (!removeRecoveredSource(src)) {<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      src.getStats());<a name="line.540"></a>
+<span class="sourceLineNo">541</span>  }<a name="line.541"></a>
+<span class="sourceLineNo">542</span><a name="line.542"></a>
+<span class="sourceLineNo">543</span>  /**<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param src source to clear<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   */<a name="line.546"></a>
+<span class="sourceLineNo">547</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    this.sources.remove(src.getPeerId());<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    // Delete queue from storage and memory<a name="line.550"></a>
+<span class="sourceLineNo">551</span>    deleteQueue(src.getQueueId());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    this.walsById.remove(src.getQueueId());<a name="line.552"></a>
+<span class="sourceLineNo">553</span><a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
+<span class="sourceLineNo">557</span>   * Delete a complete queue of wals associated with a replication source<a name="line.557"></a>
+<span class="sourceLineNo">558</span>   * @param queueId the id of replication queue to delete<a name="line.558"></a>
+<span class="sourceLineNo">559</span>   */<a name="line.559"></a>
+<span class="sourceLineNo">560</span>  private void deleteQueue(String queueId) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.561"></a>
+<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
+<span class="sourceLineNo">563</span><a name="line.563"></a>
+<span class="sourceLineNo">564</span>  @FunctionalInterface<a name="line.564"></a>
+<span class="sourceLineNo">565</span>  private interface ReplicationQueueOperation {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    void exec() throws ReplicationException;<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>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.570"></a>
+<span class="sourceLineNo">571</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   */<a name="line.572"></a>
+<span class="sourceLineNo">573</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.573"></a>
+<span class="sourceLineNo">574</span>    try {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>      op.exec();<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    } catch (ReplicationException e) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.577"></a>
+<span class="sourceLineNo">578</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.578"></a>
+<span class="sourceLineNo">579</span>          .getCause() instanceof InterruptedException) {<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        throw new RuntimeException(<a name="line.580"></a>
+<span class="sourceLineNo">581</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.581"></a>
+<span class="sourceLineNo">582</span>      }<a name="line.582"></a>
+<span class="sourceLineNo">583</span>      server.abort("Failed to operate on replication queue", e);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    }<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.587"></a>
+<span class="sourceLineNo">588</span>    try {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>      op.exec();<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    } catch (ReplicationException e) {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>      server.abort("Failed to operate on replication queue", e);<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><a name="line.594"></a>
+<span class="sourceLineNo">595</span>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    try {<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      op.exec();<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    } catch (ReplicationException e) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      throw new IOException(e);<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>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    try {<a name="line.604"></a>
+<span class="sourceLineNo">605</span>      op.exec();<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    } catch (ReplicationException e) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      server.abort("Failed to operate on replication queue", e);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      throw new IOException(e);<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>  /**<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.613"></a>
+<span class="sourceLineNo">614</span>   * replication queue.<a name="line.614"></a>
+<span class="sourceLineNo">615</span>   * @param source the replication source<a name="line.615"></a>
+<span class="sourceLineNo">616</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.616"></a>
+<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
+<span class="sourceLineNo">618</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      WALEntryBatch entryBatch) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<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>  /**<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   * file is closed and has no more entries.<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param log Path to the log<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param inclusive whether we should also remove the given log file<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @param source the replication source<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   */<a name="line.632"></a>
+<span class="sourceLineNo">633</span>  @VisibleForTesting<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.635"></a>
+<span class="sourceLineNo">636</span>    if (source.isRecovered()) {<a name="line.636"></a>
+<span class="sourceLineNo">637</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (wals != null) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.639"></a>
+<span class="sourceLineNo">640</span>        if (walsToRemove.isEmpty()) {<a name="line.640"></a>
+<span class="sourceLineNo">641</span>          return;<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        }<a name="line.642"></a>
+<span class="sourceLineNo">643</span>        cleanOldLogs(walsToRemove, source);<a name="line.643"></a>
+<span class="sourceLineNo">644</span>        walsToRemove.clear();<a name="line.644"></a>
+<span class="sourceLineNo">645</span>      }<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    } else {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      NavigableSet&lt;String&gt; wals;<a name="line.647"></a>
+<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      synchronized (this.walsById) {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        if (wals == null) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>          return;<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        }<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (walsToRemove.isEmpty()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return;<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      }<a name="line.660"></a>
+<span class="sourceLineNo">661</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.662"></a>
+<span class="sourceLineNo">663</span>      // the lock to avoid block preLogRoll<a name="line.663"></a>
+<span class="sourceLineNo">664</span>      cleanOldLogs(walsToRemove, source);<a name="line.664"></a>
+<span class="sourceLineNo">665</span>      // now let's remove the files in the set<a name="line.665"></a>
+<span class="sourceLineNo">666</span>      synchronized (this.walsById) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>        wals.removeAll(walsToRemove);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>      }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    }<a name="line.669"></a>
+<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
+<span class="sourceLineNo">671</span><a name="line.671"></a>
+<span class="sourceLineNo">672</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.672"></a>
+<span class="sourceLineNo">673</span>      throws IOException {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    for (String wal : wals) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      try {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          throw new IOException("Can not delete " + walFile);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>        }<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      } catch (FileNotFoundException e) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>        // Just ignore since this means the file has already been deleted.<a name="line.683"></a>
+<span class="sourceLineNo">684</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.684"></a>
+<span class="sourceLineNo">685</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.685"></a>
+<span class="sourceLineNo">686</span>        // FileSystem.delete, and also catch FNFE.<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<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>  }<a name="line.69

<TRUNCATED>

[24/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RandomCandidateGenerator.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo"

<TRUNCATED>

[05/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
index 13b918c..fe1ee7f 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
@@ -139,7 +139,7 @@
 <span class="sourceLineNo">131</span>      when(rl.getWriteRequestCount()).thenReturn(0L);<a name="line.131"></a>
 <span class="sourceLineNo">132</span>      when(rl.getMemStoreSize()).thenReturn(Size.ZERO);<a name="line.132"></a>
 <span class="sourceLineNo">133</span>      when(rl.getStoreFileSize()).thenReturn(Size.ZERO);<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      regionLoadMap.put(info.getEncodedNameAsBytes(), rl);<a name="line.134"></a>
+<span class="sourceLineNo">134</span>      regionLoadMap.put(info.getRegionName(), rl);<a name="line.134"></a>
 <span class="sourceLineNo">135</span>    }<a name="line.135"></a>
 <span class="sourceLineNo">136</span>    when(serverMetrics.getRegionMetrics()).thenReturn(regionLoadMap);<a name="line.136"></a>
 <span class="sourceLineNo">137</span>    return serverMetrics;<a name="line.137"></a>
@@ -230,273 +230,275 @@
 <span class="sourceLineNo">222</span><a name="line.222"></a>
 <span class="sourceLineNo">223</span>      loadBalancer.setClusterMetrics(clusterStatus);<a name="line.223"></a>
 <span class="sourceLineNo">224</span>    }<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    assertTrue(loadBalancer.loads.get(REGION_KEY) != null);<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    assertTrue(loadBalancer.loads.get(REGION_KEY).size() == 15);<a name="line.226"></a>
-<span class="sourceLineNo">227</span><a name="line.227"></a>
-<span class="sourceLineNo">228</span>    Queue&lt;BalancerRegionLoad&gt; loads = loadBalancer.loads.get(REGION_KEY);<a name="line.228"></a>
-<span class="sourceLineNo">229</span>    int i = 0;<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    while(loads.size() &gt; 0) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>      BalancerRegionLoad rl = loads.remove();<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      assertEquals(i + (numClusterStatusToAdd - 15), rl.getStorefileSizeMB());<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      i ++;<a name="line.233"></a>
-<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
-<span class="sourceLineNo">235</span>  }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>  @Test<a name="line.237"></a>
-<span class="sourceLineNo">238</span>  public void testNeedBalance() {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);<a name="line.239"></a>
-<span class="sourceLineNo">240</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);<a name="line.240"></a>
-<span class="sourceLineNo">241</span>    loadBalancer.setConf(conf);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; servers = mockClusterServers(mockCluster);<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(servers);<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      assertNull(plans);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    // reset config<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);<a name="line.248"></a>
-<span class="sourceLineNo">249</span>    loadBalancer.setConf(conf);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>  }<a name="line.250"></a>
-<span class="sourceLineNo">251</span><a name="line.251"></a>
-<span class="sourceLineNo">252</span>  @Test<a name="line.252"></a>
-<span class="sourceLineNo">253</span>  public void testLocalityCost() throws Exception {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    Configuration conf = HBaseConfiguration.create();<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    MockNoopMasterServices master = new MockNoopMasterServices();<a name="line.255"></a>
-<span class="sourceLineNo">256</span>    StochasticLoadBalancer.CostFunction<a name="line.256"></a>
-<span class="sourceLineNo">257</span>        costFunction = new ServerLocalityCostFunction(conf, master);<a name="line.257"></a>
-<span class="sourceLineNo">258</span><a name="line.258"></a>
-<span class="sourceLineNo">259</span>    for (int test = 0; test &lt; clusterRegionLocationMocks.length; test++) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      int[][] clusterRegionLocations = clusterRegionLocationMocks[test];<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      MockCluster cluster = new MockCluster(clusterRegionLocations);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      costFunction.init(cluster);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      double cost = costFunction.cost();<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      double expected = 1 - expectedLocalities[test];<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      assertEquals(expected, cost, 0.001);<a name="line.265"></a>
-<span class="sourceLineNo">266</span>    }<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  }<a name="line.267"></a>
-<span class="sourceLineNo">268</span><a name="line.268"></a>
-<span class="sourceLineNo">269</span>  @Test<a name="line.269"></a>
-<span class="sourceLineNo">270</span>  public void testMoveCost() throws Exception {<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    Configuration conf = HBaseConfiguration.create();<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    StochasticLoadBalancer.CostFunction<a name="line.272"></a>
-<span class="sourceLineNo">273</span>        costFunction = new StochasticLoadBalancer.MoveCostFunction(conf);<a name="line.273"></a>
-<span class="sourceLineNo">274</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      costFunction.init(cluster);<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      double cost = costFunction.cost();<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      assertEquals(0.0f, cost, 0.001);<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>      // cluster region number is smaller than maxMoves=600<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      cluster.setNumRegions(200);<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      cluster.setNumMovedRegions(10);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      cost = costFunction.cost();<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      assertEquals(0.05f, cost, 0.001);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>      cluster.setNumMovedRegions(100);<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      cost = costFunction.cost();<a name="line.286"></a>
-<span class="sourceLineNo">287</span>      assertEquals(0.5f, cost, 0.001);<a name="line.287"></a>
-<span class="sourceLineNo">288</span>      cluster.setNumMovedRegions(200);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>      cost = costFunction.cost();<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      assertEquals(1.0f, cost, 0.001);<a name="line.290"></a>
-<span class="sourceLineNo">291</span><a name="line.291"></a>
-<span class="sourceLineNo">292</span><a name="line.292"></a>
-<span class="sourceLineNo">293</span>      // cluster region number is bigger than maxMoves=2500<a name="line.293"></a>
-<span class="sourceLineNo">294</span>      cluster.setNumRegions(10000);<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      cluster.setNumMovedRegions(250);<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      cost = costFunction.cost();<a name="line.296"></a>
-<span class="sourceLineNo">297</span>      assertEquals(0.1f, cost, 0.001);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>      cluster.setNumMovedRegions(1250);<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      cost = costFunction.cost();<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      assertEquals(0.5f, cost, 0.001);<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      cluster.setNumMovedRegions(2500);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      cost = costFunction.cost();<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      assertEquals(1.0f, cost, 0.01);<a name="line.303"></a>
-<span class="sourceLineNo">304</span>    }<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  @Test<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  public void testSkewCost() {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    Configuration conf = HBaseConfiguration.create();<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    StochasticLoadBalancer.CostFunction<a name="line.310"></a>
-<span class="sourceLineNo">311</span>        costFunction = new StochasticLoadBalancer.RegionCountSkewCostFunction(conf);<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      costFunction.init(mockCluster(mockCluster));<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      double cost = costFunction.cost();<a name="line.314"></a>
-<span class="sourceLineNo">315</span>      assertTrue(cost &gt;= 0);<a name="line.315"></a>
-<span class="sourceLineNo">316</span>      assertTrue(cost &lt;= 1.01);<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    }<a name="line.317"></a>
-<span class="sourceLineNo">318</span><a name="line.318"></a>
-<span class="sourceLineNo">319</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    assertEquals(0,costFunction.cost(), 0.01);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 1, 1}));<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    costFunction.init(mockCluster(new int[]{0, 0, 1, 1, 1}));<a name="line.323"></a>
+<span class="sourceLineNo">225</span><a name="line.225"></a>
+<span class="sourceLineNo">226</span>    String regionNameAsString = RegionInfo.getRegionNameAsString(Bytes.toBytes(REGION_KEY));<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    assertTrue(loadBalancer.loads.get(regionNameAsString) != null);<a name="line.227"></a>
+<span class="sourceLineNo">228</span>    assertTrue(loadBalancer.loads.get(regionNameAsString).size() == 15);<a name="line.228"></a>
+<span class="sourceLineNo">229</span><a name="line.229"></a>
+<span class="sourceLineNo">230</span>    Queue&lt;BalancerRegionLoad&gt; loads = loadBalancer.loads.get(regionNameAsString);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    int i = 0;<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    while(loads.size() &gt; 0) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      BalancerRegionLoad rl = loads.remove();<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      assertEquals(i + (numClusterStatusToAdd - 15), rl.getStorefileSizeMB());<a name="line.234"></a>
+<span class="sourceLineNo">235</span>      i ++;<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    }<a name="line.236"></a>
+<span class="sourceLineNo">237</span>  }<a name="line.237"></a>
+<span class="sourceLineNo">238</span><a name="line.238"></a>
+<span class="sourceLineNo">239</span>  @Test<a name="line.239"></a>
+<span class="sourceLineNo">240</span>  public void testNeedBalance() {<a name="line.240"></a>
+<span class="sourceLineNo">241</span>    float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);<a name="line.241"></a>
+<span class="sourceLineNo">242</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    loadBalancer.setConf(conf);<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; servers = mockClusterServers(mockCluster);<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(servers);<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      assertNull(plans);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    }<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    // reset config<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    loadBalancer.setConf(conf);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>  }<a name="line.252"></a>
+<span class="sourceLineNo">253</span><a name="line.253"></a>
+<span class="sourceLineNo">254</span>  @Test<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  public void testLocalityCost() throws Exception {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    Configuration conf = HBaseConfiguration.create();<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    MockNoopMasterServices master = new MockNoopMasterServices();<a name="line.257"></a>
+<span class="sourceLineNo">258</span>    StochasticLoadBalancer.CostFunction<a name="line.258"></a>
+<span class="sourceLineNo">259</span>        costFunction = new ServerLocalityCostFunction(conf, master);<a name="line.259"></a>
+<span class="sourceLineNo">260</span><a name="line.260"></a>
+<span class="sourceLineNo">261</span>    for (int test = 0; test &lt; clusterRegionLocationMocks.length; test++) {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      int[][] clusterRegionLocations = clusterRegionLocationMocks[test];<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      MockCluster cluster = new MockCluster(clusterRegionLocations);<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      costFunction.init(cluster);<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      double cost = costFunction.cost();<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      double expected = 1 - expectedLocalities[test];<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      assertEquals(expected, cost, 0.001);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    }<a name="line.268"></a>
+<span class="sourceLineNo">269</span>  }<a name="line.269"></a>
+<span class="sourceLineNo">270</span><a name="line.270"></a>
+<span class="sourceLineNo">271</span>  @Test<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  public void testMoveCost() throws Exception {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>    Configuration conf = HBaseConfiguration.create();<a name="line.273"></a>
+<span class="sourceLineNo">274</span>    StochasticLoadBalancer.CostFunction<a name="line.274"></a>
+<span class="sourceLineNo">275</span>        costFunction = new StochasticLoadBalancer.MoveCostFunction(conf);<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      costFunction.init(cluster);<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      double cost = costFunction.cost();<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      assertEquals(0.0f, cost, 0.001);<a name="line.280"></a>
+<span class="sourceLineNo">281</span><a name="line.281"></a>
+<span class="sourceLineNo">282</span>      // cluster region number is smaller than maxMoves=600<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      cluster.setNumRegions(200);<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      cluster.setNumMovedRegions(10);<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      cost = costFunction.cost();<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      assertEquals(0.05f, cost, 0.001);<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      cluster.setNumMovedRegions(100);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      cost = costFunction.cost();<a name="line.288"></a>
+<span class="sourceLineNo">289</span>      assertEquals(0.5f, cost, 0.001);<a name="line.289"></a>
+<span class="sourceLineNo">290</span>      cluster.setNumMovedRegions(200);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      cost = costFunction.cost();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      assertEquals(1.0f, cost, 0.001);<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span><a name="line.294"></a>
+<span class="sourceLineNo">295</span>      // cluster region number is bigger than maxMoves=2500<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      cluster.setNumRegions(10000);<a name="line.296"></a>
+<span class="sourceLineNo">297</span>      cluster.setNumMovedRegions(250);<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      cost = costFunction.cost();<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      assertEquals(0.1f, cost, 0.001);<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      cluster.setNumMovedRegions(1250);<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      cost = costFunction.cost();<a name="line.301"></a>
+<span class="sourceLineNo">302</span>      assertEquals(0.5f, cost, 0.001);<a name="line.302"></a>
+<span class="sourceLineNo">303</span>      cluster.setNumMovedRegions(2500);<a name="line.303"></a>
+<span class="sourceLineNo">304</span>      cost = costFunction.cost();<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      assertEquals(1.0f, cost, 0.01);<a name="line.305"></a>
+<span class="sourceLineNo">306</span>    }<a name="line.306"></a>
+<span class="sourceLineNo">307</span>  }<a name="line.307"></a>
+<span class="sourceLineNo">308</span><a name="line.308"></a>
+<span class="sourceLineNo">309</span>  @Test<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  public void testSkewCost() {<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    Configuration conf = HBaseConfiguration.create();<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    StochasticLoadBalancer.CostFunction<a name="line.312"></a>
+<span class="sourceLineNo">313</span>        costFunction = new StochasticLoadBalancer.RegionCountSkewCostFunction(conf);<a name="line.313"></a>
+<span class="sourceLineNo">314</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.314"></a>
+<span class="sourceLineNo">315</span>      costFunction.init(mockCluster(mockCluster));<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      double cost = costFunction.cost();<a name="line.316"></a>
+<span class="sourceLineNo">317</span>      assertTrue(cost &gt;= 0);<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      assertTrue(cost &lt;= 1.01);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
+<span class="sourceLineNo">320</span><a name="line.320"></a>
+<span class="sourceLineNo">321</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    assertEquals(0,costFunction.cost(), 0.01);<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 1, 1}));<a name="line.323"></a>
 <span class="sourceLineNo">324</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    costFunction.init(mockCluster(new int[]{0, 1, 1, 1, 1}));<a name="line.325"></a>
+<span class="sourceLineNo">325</span>    costFunction.init(mockCluster(new int[]{0, 0, 1, 1, 1}));<a name="line.325"></a>
 <span class="sourceLineNo">326</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    costFunction.init(mockCluster(new int[]{1, 1, 1, 1, 1}));<a name="line.327"></a>
+<span class="sourceLineNo">327</span>    costFunction.init(mockCluster(new int[]{0, 1, 1, 1, 1}));<a name="line.327"></a>
 <span class="sourceLineNo">328</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    costFunction.init(mockCluster(new int[]{10000, 0, 0, 0, 0}));<a name="line.329"></a>
-<span class="sourceLineNo">330</span>    assertEquals(1, costFunction.cost(), 0.01);<a name="line.330"></a>
-<span class="sourceLineNo">331</span>  }<a name="line.331"></a>
-<span class="sourceLineNo">332</span><a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Test<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public void testCostAfterUndoAction() {<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    final int runs = 10;<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    loadBalancer.setConf(conf);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      loadBalancer.initCosts(cluster);<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      for (int i = 0; i != runs; ++i) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        final double expectedCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        Cluster.Action action = loadBalancer.nextAction(cluster);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        cluster.doAction(action);<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        loadBalancer.updateCostsWithAction(cluster, action);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        Cluster.Action undoAction = action.undoAction();<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        cluster.doAction(undoAction);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadBalancer.updateCostsWithAction(cluster, undoAction);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        final double actualCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>        assertEquals(expectedCost, actualCost, 0);<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    }<a name="line.351"></a>
-<span class="sourceLineNo">352</span>  }<a name="line.352"></a>
-<span class="sourceLineNo">353</span><a name="line.353"></a>
-<span class="sourceLineNo">354</span>  @Test<a name="line.354"></a>
-<span class="sourceLineNo">355</span>  public void testTableSkewCost() {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    Configuration conf = HBaseConfiguration.create();<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    StochasticLoadBalancer.CostFunction<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        costFunction = new StochasticLoadBalancer.TableSkewCostFunction(conf);<a name="line.358"></a>
-<span class="sourceLineNo">359</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      costFunction.init(cluster);<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      double cost = costFunction.cost();<a name="line.362"></a>
-<span class="sourceLineNo">363</span>      assertTrue(cost &gt;= 0);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      assertTrue(cost &lt;= 1.01);<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><a name="line.367"></a>
-<span class="sourceLineNo">368</span>  @Test<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  public void testRegionLoadCost() {<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    List&lt;BalancerRegionLoad&gt; regionLoads = new ArrayList&lt;&gt;();<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    for (int i = 1; i &lt; 5; i++) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      BalancerRegionLoad regionLoad = mock(BalancerRegionLoad.class);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>      when(regionLoad.getReadRequestsCount()).thenReturn(new Long(i));<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      when(regionLoad.getCpRequestsCount()).thenReturn(new Long(i));<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      when(regionLoad.getStorefileSizeMB()).thenReturn(i);<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      regionLoads.add(regionLoad);<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    }<a name="line.377"></a>
-<span class="sourceLineNo">378</span><a name="line.378"></a>
-<span class="sourceLineNo">379</span>    Configuration conf = HBaseConfiguration.create();<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    StochasticLoadBalancer.ReadRequestCostFunction readCostFunction =<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        new StochasticLoadBalancer.ReadRequestCostFunction(conf);<a name="line.381"></a>
-<span class="sourceLineNo">382</span>    double rateResult = readCostFunction.getRegionLoadCost(regionLoads);<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    // read requests are treated as a rate so the average rate here is simply 1<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    assertEquals(1, rateResult, 0.01);<a name="line.384"></a>
-<span class="sourceLineNo">385</span><a name="line.385"></a>
-<span class="sourceLineNo">386</span>    StochasticLoadBalancer.CPRequestCostFunction cpCostFunction =<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        new StochasticLoadBalancer.CPRequestCostFunction(conf);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    rateResult = cpCostFunction.getRegionLoadCost(regionLoads);<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // coprocessor requests are treated as a rate so the average rate here is simply 1<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    assertEquals(1, rateResult, 0.01);<a name="line.390"></a>
-<span class="sourceLineNo">391</span><a name="line.391"></a>
-<span class="sourceLineNo">392</span>    StochasticLoadBalancer.StoreFileCostFunction storeFileCostFunction =<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        new StochasticLoadBalancer.StoreFileCostFunction(conf);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    double result = storeFileCostFunction.getRegionLoadCost(regionLoads);<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    // storefile size cost is simply an average of it's value over time<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    assertEquals(2.5, result, 0.01);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>  }<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>  @Test<a name="line.399"></a>
-<span class="sourceLineNo">400</span>  public void testCostFromArray() {<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    Configuration conf = HBaseConfiguration.create();<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    StochasticLoadBalancer.CostFromRegionLoadFunction<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        costFunction = new StochasticLoadBalancer.MemStoreSizeCostFunction(conf);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.404"></a>
-<span class="sourceLineNo">405</span><a name="line.405"></a>
-<span class="sourceLineNo">406</span>    double[] statOne = new double[100];<a name="line.406"></a>
-<span class="sourceLineNo">407</span>    for (int i =0; i &lt; 100; i++) {<a name="line.407"></a>
-<span class="sourceLineNo">408</span>      statOne[i] = 10;<a name="line.408"></a>
-<span class="sourceLineNo">409</span>    }<a name="line.409"></a>
-<span class="sourceLineNo">410</span>    assertEquals(0, costFunction.costFromArray(statOne), 0.01);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>    double[] statTwo= new double[101];<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    for (int i =0; i &lt; 100; i++) {<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      statTwo[i] = 0;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    statTwo[100] = 100;<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    assertEquals(1, costFunction.costFromArray(statTwo), 0.01);<a name="line.417"></a>
-<span class="sourceLineNo">418</span><a name="line.418"></a>
-<span class="sourceLineNo">419</span>    double[] statThree = new double[200];<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    for (int i =0; i &lt; 100; i++) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>      statThree[i] = (0);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      statThree[i+100] = 100;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>    assertEquals(0.5, costFunction.costFromArray(statThree), 0.01);<a name="line.424"></a>
-<span class="sourceLineNo">425</span>  }<a name="line.425"></a>
-<span class="sourceLineNo">426</span><a name="line.426"></a>
-<span class="sourceLineNo">427</span>  @Test<a name="line.427"></a>
-<span class="sourceLineNo">428</span>  public void testLosingRs() throws Exception {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    int numNodes = 3;<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    int numRegions = 20;<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    int numRegionsPerServer = 3; //all servers except one<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    int replication = 1;<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    int numTables = 2;<a name="line.433"></a>
-<span class="sourceLineNo">434</span><a name="line.434"></a>
-<span class="sourceLineNo">435</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.435"></a>
-<span class="sourceLineNo">436</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    List&lt;ServerAndLoad&gt; list = convertToList(serverMap);<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>    List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(serverMap);<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    assertNotNull(plans);<a name="line.441"></a>
-<span class="sourceLineNo">442</span><a name="line.442"></a>
-<span class="sourceLineNo">443</span>    // Apply the plan to the mock cluster.<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    List&lt;ServerAndLoad&gt; balancedCluster = reconcile(list, plans, serverMap);<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    assertClusterAsBalanced(balancedCluster);<a name="line.446"></a>
+<span class="sourceLineNo">329</span>    costFunction.init(mockCluster(new int[]{1, 1, 1, 1, 1}));<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    assertEquals(0, costFunction.cost(), 0.01);<a name="line.330"></a>
+<span class="sourceLineNo">331</span>    costFunction.init(mockCluster(new int[]{10000, 0, 0, 0, 0}));<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    assertEquals(1, costFunction.cost(), 0.01);<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  }<a name="line.333"></a>
+<span class="sourceLineNo">334</span><a name="line.334"></a>
+<span class="sourceLineNo">335</span>  @Test<a name="line.335"></a>
+<span class="sourceLineNo">336</span>  public void testCostAfterUndoAction() {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    final int runs = 10;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    loadBalancer.setConf(conf);<a name="line.338"></a>
+<span class="sourceLineNo">339</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      loadBalancer.initCosts(cluster);<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      for (int i = 0; i != runs; ++i) {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        final double expectedCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        Cluster.Action action = loadBalancer.nextAction(cluster);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        cluster.doAction(action);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>        loadBalancer.updateCostsWithAction(cluster, action);<a name="line.346"></a>
+<span class="sourceLineNo">347</span>        Cluster.Action undoAction = action.undoAction();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>        cluster.doAction(undoAction);<a name="line.348"></a>
+<span class="sourceLineNo">349</span>        loadBalancer.updateCostsWithAction(cluster, undoAction);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        final double actualCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        assertEquals(expectedCost, actualCost, 0);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      }<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    }<a name="line.353"></a>
+<span class="sourceLineNo">354</span>  }<a name="line.354"></a>
+<span class="sourceLineNo">355</span><a name="line.355"></a>
+<span class="sourceLineNo">356</span>  @Test<a name="line.356"></a>
+<span class="sourceLineNo">357</span>  public void testTableSkewCost() {<a name="line.357"></a>
+<span class="sourceLineNo">358</span>    Configuration conf = HBaseConfiguration.create();<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    StochasticLoadBalancer.CostFunction<a name="line.359"></a>
+<span class="sourceLineNo">360</span>        costFunction = new StochasticLoadBalancer.TableSkewCostFunction(conf);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    for (int[] mockCluster : clusterStateMocks) {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>      BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      costFunction.init(cluster);<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      double cost = costFunction.cost();<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      assertTrue(cost &gt;= 0);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      assertTrue(cost &lt;= 1.01);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    }<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
+<span class="sourceLineNo">369</span><a name="line.369"></a>
+<span class="sourceLineNo">370</span>  @Test<a name="line.370"></a>
+<span class="sourceLineNo">371</span>  public void testRegionLoadCost() {<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    List&lt;BalancerRegionLoad&gt; regionLoads = new ArrayList&lt;&gt;();<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 1; i &lt; 5; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      BalancerRegionLoad regionLoad = mock(BalancerRegionLoad.class);<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      when(regionLoad.getReadRequestsCount()).thenReturn(new Long(i));<a name="line.375"></a>
+<span class="sourceLineNo">376</span>      when(regionLoad.getCpRequestsCount()).thenReturn(new Long(i));<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      when(regionLoad.getStorefileSizeMB()).thenReturn(i);<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      regionLoads.add(regionLoad);<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    }<a name="line.379"></a>
+<span class="sourceLineNo">380</span><a name="line.380"></a>
+<span class="sourceLineNo">381</span>    Configuration conf = HBaseConfiguration.create();<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    StochasticLoadBalancer.ReadRequestCostFunction readCostFunction =<a name="line.382"></a>
+<span class="sourceLineNo">383</span>        new StochasticLoadBalancer.ReadRequestCostFunction(conf);<a name="line.383"></a>
+<span class="sourceLineNo">384</span>    double rateResult = readCostFunction.getRegionLoadCost(regionLoads);<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    // read requests are treated as a rate so the average rate here is simply 1<a name="line.385"></a>
+<span class="sourceLineNo">386</span>    assertEquals(1, rateResult, 0.01);<a name="line.386"></a>
+<span class="sourceLineNo">387</span><a name="line.387"></a>
+<span class="sourceLineNo">388</span>    StochasticLoadBalancer.CPRequestCostFunction cpCostFunction =<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        new StochasticLoadBalancer.CPRequestCostFunction(conf);<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    rateResult = cpCostFunction.getRegionLoadCost(regionLoads);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    // coprocessor requests are treated as a rate so the average rate here is simply 1<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    assertEquals(1, rateResult, 0.01);<a name="line.392"></a>
+<span class="sourceLineNo">393</span><a name="line.393"></a>
+<span class="sourceLineNo">394</span>    StochasticLoadBalancer.StoreFileCostFunction storeFileCostFunction =<a name="line.394"></a>
+<span class="sourceLineNo">395</span>        new StochasticLoadBalancer.StoreFileCostFunction(conf);<a name="line.395"></a>
+<span class="sourceLineNo">396</span>    double result = storeFileCostFunction.getRegionLoadCost(regionLoads);<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    // storefile size cost is simply an average of it's value over time<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    assertEquals(2.5, result, 0.01);<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  }<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>  @Test<a name="line.401"></a>
+<span class="sourceLineNo">402</span>  public void testCostFromArray() {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>    Configuration conf = HBaseConfiguration.create();<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    StochasticLoadBalancer.CostFromRegionLoadFunction<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        costFunction = new StochasticLoadBalancer.MemStoreSizeCostFunction(conf);<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>    double[] statOne = new double[100];<a name="line.408"></a>
+<span class="sourceLineNo">409</span>    for (int i =0; i &lt; 100; i++) {<a name="line.409"></a>
+<span class="sourceLineNo">410</span>      statOne[i] = 10;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    assertEquals(0, costFunction.costFromArray(statOne), 0.01);<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    double[] statTwo= new double[101];<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    for (int i =0; i &lt; 100; i++) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      statTwo[i] = 0;<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    statTwo[100] = 100;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    assertEquals(1, costFunction.costFromArray(statTwo), 0.01);<a name="line.419"></a>
+<span class="sourceLineNo">420</span><a name="line.420"></a>
+<span class="sourceLineNo">421</span>    double[] statThree = new double[200];<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    for (int i =0; i &lt; 100; i++) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>      statThree[i] = (0);<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      statThree[i+100] = 100;<a name="line.424"></a>
+<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
+<span class="sourceLineNo">426</span>    assertEquals(0.5, costFunction.costFromArray(statThree), 0.01);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>  }<a name="line.427"></a>
+<span class="sourceLineNo">428</span><a name="line.428"></a>
+<span class="sourceLineNo">429</span>  @Test<a name="line.429"></a>
+<span class="sourceLineNo">430</span>  public void testLosingRs() throws Exception {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    int numNodes = 3;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    int numRegions = 20;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>    int numRegionsPerServer = 3; //all servers except one<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    int replication = 1;<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    int numTables = 2;<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>    Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; serverMap =<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>    List&lt;ServerAndLoad&gt; list = convertToList(serverMap);<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>    List&lt;RegionPlan&gt; plans = loadBalancer.balanceCluster(serverMap);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    assertNotNull(plans);<a name="line.443"></a>
+<span class="sourceLineNo">444</span><a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // Apply the plan to the mock cluster.<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    List&lt;ServerAndLoad&gt; balancedCluster = reconcile(list, plans, serverMap);<a name="line.446"></a>
 <span class="sourceLineNo">447</span><a name="line.447"></a>
-<span class="sourceLineNo">448</span>    ServerName sn = serverMap.keySet().toArray(new ServerName[serverMap.size()])[0];<a name="line.448"></a>
+<span class="sourceLineNo">448</span>    assertClusterAsBalanced(balancedCluster);<a name="line.448"></a>
 <span class="sourceLineNo">449</span><a name="line.449"></a>
-<span class="sourceLineNo">450</span>    ServerName deadSn = ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 100);<a name="line.450"></a>
+<span class="sourceLineNo">450</span>    ServerName sn = serverMap.keySet().toArray(new ServerName[serverMap.size()])[0];<a name="line.450"></a>
 <span class="sourceLineNo">451</span><a name="line.451"></a>
-<span class="sourceLineNo">452</span>    serverMap.put(deadSn, new ArrayList&lt;&gt;(0));<a name="line.452"></a>
+<span class="sourceLineNo">452</span>    ServerName deadSn = ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 100);<a name="line.452"></a>
 <span class="sourceLineNo">453</span><a name="line.453"></a>
-<span class="sourceLineNo">454</span>    plans = loadBalancer.balanceCluster(serverMap);<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    assertNull(plans);<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  // This mock allows us to test the LocalityCostFunction<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  private class MockCluster extends BaseLoadBalancer.Cluster {<a name="line.459"></a>
-<span class="sourceLineNo">460</span><a name="line.460"></a>
-<span class="sourceLineNo">461</span>    private int[][] localities = null;   // [region][server] = percent of blocks<a name="line.461"></a>
+<span class="sourceLineNo">454</span>    serverMap.put(deadSn, new ArrayList&lt;&gt;(0));<a name="line.454"></a>
+<span class="sourceLineNo">455</span><a name="line.455"></a>
+<span class="sourceLineNo">456</span>    plans = loadBalancer.balanceCluster(serverMap);<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    assertNull(plans);<a name="line.457"></a>
+<span class="sourceLineNo">458</span>  }<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>  // This mock allows us to test the LocalityCostFunction<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  private class MockCluster extends BaseLoadBalancer.Cluster {<a name="line.461"></a>
 <span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    public MockCluster(int[][] regions) {<a name="line.463"></a>
+<span class="sourceLineNo">463</span>    private int[][] localities = null;   // [region][server] = percent of blocks<a name="line.463"></a>
 <span class="sourceLineNo">464</span><a name="line.464"></a>
-<span class="sourceLineNo">465</span>      // regions[0] is an array where index = serverIndex an value = number of regions<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      super(mockClusterServers(regions[0], 1), null, null, null);<a name="line.466"></a>
-<span class="sourceLineNo">467</span><a name="line.467"></a>
-<span class="sourceLineNo">468</span>      localities = new int[regions.length - 1][];<a name="line.468"></a>
-<span class="sourceLineNo">469</span>      for (int i = 1; i &lt; regions.length; i++) {<a name="line.469"></a>
-<span class="sourceLineNo">470</span>        int regionIndex = i - 1;<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        localities[regionIndex] = new int[regions[i].length - 1];<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        regionIndexToServerIndex[regionIndex] = regions[i][0];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        for (int j = 1; j &lt; regions[i].length; j++) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>          int serverIndex = j - 1;<a name="line.474"></a>
-<span class="sourceLineNo">475</span>          localities[regionIndex][serverIndex] = regions[i][j] &gt; 100 ? regions[i][j] % 100 : regions[i][j];<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        }<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    }<a name="line.478"></a>
-<span class="sourceLineNo">479</span><a name="line.479"></a>
-<span class="sourceLineNo">480</span>    @Override<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    float getLocalityOfRegion(int region, int server) {<a name="line.481"></a>
-<span class="sourceLineNo">482</span>      // convert the locality percentage to a fraction<a name="line.482"></a>
-<span class="sourceLineNo">483</span>      return localities[region][server] / 100.0f;<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    }<a name="line.484"></a>
-<span class="sourceLineNo">485</span><a name="line.485"></a>
-<span class="sourceLineNo">486</span>    @Override<a name="line.486"></a>
-<span class="sourceLineNo">487</span>    public int getRegionSizeMB(int region) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      return 1;<a name="line.488"></a>
-<span class="sourceLineNo">489</span>    }<a name="line.489"></a>
-<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>}<a name="line.491"></a>
+<span class="sourceLineNo">465</span>    public MockCluster(int[][] regions) {<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>      // regions[0] is an array where index = serverIndex an value = number of regions<a name="line.467"></a>
+<span class="sourceLineNo">468</span>      super(mockClusterServers(regions[0], 1), null, null, null);<a name="line.468"></a>
+<span class="sourceLineNo">469</span><a name="line.469"></a>
+<span class="sourceLineNo">470</span>      localities = new int[regions.length - 1][];<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      for (int i = 1; i &lt; regions.length; i++) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        int regionIndex = i - 1;<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        localities[regionIndex] = new int[regions[i].length - 1];<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        regionIndexToServerIndex[regionIndex] = regions[i][0];<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        for (int j = 1; j &lt; regions[i].length; j++) {<a name="line.475"></a>
+<span class="sourceLineNo">476</span>          int serverIndex = j - 1;<a name="line.476"></a>
+<span class="sourceLineNo">477</span>          localities[regionIndex][serverIndex] = regions[i][j] &gt; 100 ? regions[i][j] % 100 : regions[i][j];<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>    }<a name="line.480"></a>
+<span class="sourceLineNo">481</span><a name="line.481"></a>
+<span class="sourceLineNo">482</span>    @Override<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    float getLocalityOfRegion(int region, int server) {<a name="line.483"></a>
+<span class="sourceLineNo">484</span>      // convert the locality percentage to a fraction<a name="line.484"></a>
+<span class="sourceLineNo">485</span>      return localities[region][server] / 100.0f;<a name="line.485"></a>
+<span class="sourceLineNo">486</span>    }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>    @Override<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    public int getRegionSizeMB(int region) {<a name="line.489"></a>
+<span class="sourceLineNo">490</span>      return 1;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
+<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
+<span class="sourceLineNo">493</span>}<a name="line.493"></a>
 
 
 


[03/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
index 006d1ba..18cf507 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyServer.html
@@ -654,258 +654,274 @@
 <span class="sourceLineNo">646</span>    }<a name="line.646"></a>
 <span class="sourceLineNo">647</span>  }<a name="line.647"></a>
 <span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>  /**<a name="line.649"></a>
-<span class="sourceLineNo">650</span>   * Add a peer and wait for it to initialize<a name="line.650"></a>
-<span class="sourceLineNo">651</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.651"></a>
-<span class="sourceLineNo">652</span>   */<a name="line.652"></a>
-<span class="sourceLineNo">653</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.653"></a>
-<span class="sourceLineNo">654</span>      final boolean waitForSource) throws Exception {<a name="line.654"></a>
-<span class="sourceLineNo">655</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>    try {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      manager.addPeer(peerId);<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    } catch (Exception e) {<a name="line.659"></a>
-<span class="sourceLineNo">660</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>    waitPeer(peerId, manager, waitForSource);<a name="line.662"></a>
-<span class="sourceLineNo">663</span>    if (managerOfCluster != null) {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      managerOfCluster.addPeer(peerId);<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>  }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>  private static void waitPeer(final String peerId,<a name="line.669"></a>
-<span class="sourceLineNo">670</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>      if (waitForSource) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>        if (rs == null) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          return false;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        }<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.678"></a>
-<span class="sourceLineNo">679</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>        return true;<a name="line.681"></a>
-<span class="sourceLineNo">682</span>      } else {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>        return (rp.getPeer(peerId) != null);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      }<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    });<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>  /**<a name="line.688"></a>
-<span class="sourceLineNo">689</span>   * Remove a peer and wait for it to get cleaned up<a name="line.689"></a>
-<span class="sourceLineNo">690</span>   * @param peerId<a name="line.690"></a>
-<span class="sourceLineNo">691</span>   * @throws Exception<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      try {<a name="line.697"></a>
-<span class="sourceLineNo">698</span>        manager.removePeer(peerId);<a name="line.698"></a>
-<span class="sourceLineNo">699</span>      } catch (Exception e) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        // ignore the failed exception and continue.<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      }<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      @Override<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      public boolean evaluate() throws Exception {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<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>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.713"></a>
-<span class="sourceLineNo">714</span>    // 1. Create store files for the families<a name="line.714"></a>
-<span class="sourceLineNo">715</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.718"></a>
-<span class="sourceLineNo">719</span>    p.add(hfilePath1);<a name="line.719"></a>
-<span class="sourceLineNo">720</span>    try {<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    } catch (IOException e) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    }<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    storeFiles.put(f1, p);<a name="line.726"></a>
-<span class="sourceLineNo">727</span>    scope.put(f1, 1);<a name="line.727"></a>
-<span class="sourceLineNo">728</span>    p = new ArrayList&lt;&gt;(1);<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.729"></a>
-<span class="sourceLineNo">730</span>    p.add(hfilePath2);<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    try {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    } catch (IOException e) {<a name="line.733"></a>
-<span class="sourceLineNo">734</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>    storeFiles.put(f2, p);<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    // 2. Create bulk load descriptor<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    BulkLoadDescriptor desc =<a name="line.739"></a>
-<span class="sourceLineNo">740</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.740"></a>
-<span class="sourceLineNo">741</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.741"></a>
-<span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    // 3. create bulk load wal edit event<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    return logEdit;<a name="line.745"></a>
-<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>  static class DummyNodeFailoverWorker extends Thread {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    Server server;<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    private ServerName deadRS;<a name="line.751"></a>
-<span class="sourceLineNo">752</span>    ReplicationQueueStorage rq;<a name="line.752"></a>
-<span class="sourceLineNo">753</span><a name="line.753"></a>
-<span class="sourceLineNo">754</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      this.deadRS = deadRS;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      this.server = s;<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.757"></a>
-<span class="sourceLineNo">758</span>        server.getConfiguration());<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>    @Override<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    public void run() {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>      try {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.764"></a>
-<span class="sourceLineNo">765</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>        for (String queue : queues) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.768"></a>
-<span class="sourceLineNo">769</span>          if (pair != null) {<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>      } catch (Exception e) {<a name="line.774"></a>
-<span class="sourceLineNo">775</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      } finally {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>        latch.countDown();<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    /**<a name="line.781"></a>
-<span class="sourceLineNo">782</span>     * @return 1 when the map is not empty.<a name="line.782"></a>
-<span class="sourceLineNo">783</span>     */<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    private int isLogZnodesMapPopulated() {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>      if (sets.size() &gt; 1) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      }<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (sets.size() == 1) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.790"></a>
-<span class="sourceLineNo">791</span>        for (String file : files) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>          // at least one file was missing<a name="line.792"></a>
-<span class="sourceLineNo">793</span>          if (!s.contains(file)) {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>            return 0;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>          }<a name="line.795"></a>
-<span class="sourceLineNo">796</span>        }<a name="line.796"></a>
-<span class="sourceLineNo">797</span>        return 1; // we found all the files<a name="line.797"></a>
-<span class="sourceLineNo">798</span>      }<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return 0;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span><a name="line.802"></a>
-<span class="sourceLineNo">803</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.803"></a>
-<span class="sourceLineNo">804</span><a name="line.804"></a>
-<span class="sourceLineNo">805</span>    @Override<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.808"></a>
-<span class="sourceLineNo">809</span>        throws IOException {<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      throw new IOException("Failing deliberately");<a name="line.810"></a>
-<span class="sourceLineNo">811</span>    }<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>  static class DummyServer implements Server {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    String hostname;<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>    DummyServer() {<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      hostname = "hostname.example.org";<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    }<a name="line.819"></a>
+<span class="sourceLineNo">649</span>  @Test<a name="line.649"></a>
+<span class="sourceLineNo">650</span>  public void testSameWALPrefix() throws IOException {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    Set&lt;String&gt; latestWalsBefore =<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      manager.getLastestPath().stream().map(Path::getName).collect(Collectors.toSet());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    String walName1 = "localhost,8080,12345-45678-Peer.34567";<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    String walName2 = "localhost,8080,12345.56789";<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    manager.preLogRoll(new Path(walName1));<a name="line.655"></a>
+<span class="sourceLineNo">656</span>    manager.preLogRoll(new Path(walName2));<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>    Set&lt;String&gt; latestWals = manager.getLastestPath().stream().map(Path::getName)<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      .filter(n -&gt; !latestWalsBefore.contains(n)).collect(Collectors.toSet());<a name="line.659"></a>
+<span class="sourceLineNo">660</span>    assertEquals(2, latestWals.size());<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    assertTrue(latestWals.contains(walName1));<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    assertTrue(latestWals.contains(walName2));<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  /**<a name="line.665"></a>
+<span class="sourceLineNo">666</span>   * Add a peer and wait for it to initialize<a name="line.666"></a>
+<span class="sourceLineNo">667</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.667"></a>
+<span class="sourceLineNo">668</span>   */<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.669"></a>
+<span class="sourceLineNo">670</span>      final boolean waitForSource) throws Exception {<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    try {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      manager.addPeer(peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    } catch (Exception e) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    waitPeer(peerId, manager, waitForSource);<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    if (managerOfCluster != null) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      managerOfCluster.addPeer(peerId);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    }<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>  private static void waitPeer(final String peerId,<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.688"></a>
+<span class="sourceLineNo">689</span>      if (waitForSource) {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        if (rs == null) {<a name="line.691"></a>
+<span class="sourceLineNo">692</span>          return false;<a name="line.692"></a>
+<span class="sourceLineNo">693</span>        }<a name="line.693"></a>
+<span class="sourceLineNo">694</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.695"></a>
+<span class="sourceLineNo">696</span>        }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>        return true;<a name="line.697"></a>
+<span class="sourceLineNo">698</span>      } else {<a name="line.698"></a>
+<span class="sourceLineNo">699</span>        return (rp.getPeer(peerId) != null);<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      }<a name="line.700"></a>
+<span class="sourceLineNo">701</span>    });<a name="line.701"></a>
+<span class="sourceLineNo">702</span>  }<a name="line.702"></a>
+<span class="sourceLineNo">703</span><a name="line.703"></a>
+<span class="sourceLineNo">704</span>  /**<a name="line.704"></a>
+<span class="sourceLineNo">705</span>   * Remove a peer and wait for it to get cleaned up<a name="line.705"></a>
+<span class="sourceLineNo">706</span>   * @param peerId<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * @throws Exception<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   */<a name="line.708"></a>
+<span class="sourceLineNo">709</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.709"></a>
+<span class="sourceLineNo">710</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.711"></a>
+<span class="sourceLineNo">712</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.712"></a>
+<span class="sourceLineNo">713</span>      try {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>        manager.removePeer(peerId);<a name="line.714"></a>
+<span class="sourceLineNo">715</span>      } catch (Exception e) {<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        // ignore the failed exception and continue.<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      }<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    }<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      @Override<a name="line.720"></a>
+<span class="sourceLineNo">721</span>      public boolean evaluate() throws Exception {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.722"></a>
+<span class="sourceLineNo">723</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.723"></a>
+<span class="sourceLineNo">724</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      }<a name="line.725"></a>
+<span class="sourceLineNo">726</span>    });<a name="line.726"></a>
+<span class="sourceLineNo">727</span>  }<a name="line.727"></a>
+<span class="sourceLineNo">728</span><a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    // 1. Create store files for the families<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.731"></a>
+<span class="sourceLineNo">732</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    p.add(hfilePath1);<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    try {<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    } catch (IOException e) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>    storeFiles.put(f1, p);<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    scope.put(f1, 1);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    p = new ArrayList&lt;&gt;(1);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.745"></a>
+<span class="sourceLineNo">746</span>    p.add(hfilePath2);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    try {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    } catch (IOException e) {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    }<a name="line.752"></a>
+<span class="sourceLineNo">753</span>    storeFiles.put(f2, p);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // 2. Create bulk load descriptor<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    BulkLoadDescriptor desc =<a name="line.755"></a>
+<span class="sourceLineNo">756</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.757"></a>
+<span class="sourceLineNo">758</span><a name="line.758"></a>
+<span class="sourceLineNo">759</span>    // 3. create bulk load wal edit event<a name="line.759"></a>
+<span class="sourceLineNo">760</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.760"></a>
+<span class="sourceLineNo">761</span>    return logEdit;<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>  static class DummyNodeFailoverWorker extends Thread {<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    Server server;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    private ServerName deadRS;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    ReplicationQueueStorage rq;<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      this.deadRS = deadRS;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      this.server = s;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        server.getConfiguration());<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    }<a name="line.775"></a>
+<span class="sourceLineNo">776</span><a name="line.776"></a>
+<span class="sourceLineNo">777</span>    @Override<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    public void run() {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>      try {<a name="line.779"></a>
+<span class="sourceLineNo">780</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.780"></a>
+<span class="sourceLineNo">781</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.781"></a>
+<span class="sourceLineNo">782</span>        for (String queue : queues) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.783"></a>
+<span class="sourceLineNo">784</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.784"></a>
+<span class="sourceLineNo">785</span>          if (pair != null) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.789"></a>
+<span class="sourceLineNo">790</span>      } catch (Exception e) {<a name="line.790"></a>
+<span class="sourceLineNo">791</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.791"></a>
+<span class="sourceLineNo">792</span>      } finally {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>        latch.countDown();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      }<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">796</span><a name="line.796"></a>
+<span class="sourceLineNo">797</span>    /**<a name="line.797"></a>
+<span class="sourceLineNo">798</span>     * @return 1 when the map is not empty.<a name="line.798"></a>
+<span class="sourceLineNo">799</span>     */<a name="line.799"></a>
+<span class="sourceLineNo">800</span>    private int isLogZnodesMapPopulated() {<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      if (sets.size() &gt; 1) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      }<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      if (sets.size() == 1) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        for (String file : files) {<a name="line.807"></a>
+<span class="sourceLineNo">808</span>          // at least one file was missing<a name="line.808"></a>
+<span class="sourceLineNo">809</span>          if (!s.contains(file)) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>            return 0;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>          }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        }<a name="line.812"></a>
+<span class="sourceLineNo">813</span>        return 1; // we found all the files<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      }<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      return 0;<a name="line.815"></a>
+<span class="sourceLineNo">816</span>    }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.819"></a>
 <span class="sourceLineNo">820</span><a name="line.820"></a>
-<span class="sourceLineNo">821</span>    DummyServer(String hostname) {<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      this.hostname = hostname;<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>    @Override<a name="line.825"></a>
-<span class="sourceLineNo">826</span>    public Configuration getConfiguration() {<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      return conf;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    }<a name="line.828"></a>
+<span class="sourceLineNo">821</span>    @Override<a name="line.821"></a>
+<span class="sourceLineNo">822</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.822"></a>
+<span class="sourceLineNo">823</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.823"></a>
+<span class="sourceLineNo">824</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.824"></a>
+<span class="sourceLineNo">825</span>        throws IOException {<a name="line.825"></a>
+<span class="sourceLineNo">826</span>      throw new IOException("Failing deliberately");<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    }<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    @Override<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    public ZKWatcher getZooKeeper() {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      return zkw;<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    }<a name="line.833"></a>
-<span class="sourceLineNo">834</span><a name="line.834"></a>
-<span class="sourceLineNo">835</span>    @Override<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>      return null;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>    }<a name="line.838"></a>
-<span class="sourceLineNo">839</span>    @Override<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    public ClusterConnection getConnection() {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      return null;<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span><a name="line.843"></a>
-<span class="sourceLineNo">844</span>    @Override<a name="line.844"></a>
-<span class="sourceLineNo">845</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.845"></a>
-<span class="sourceLineNo">846</span>      return null;<a name="line.846"></a>
-<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>    @Override<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    public ServerName getServerName() {<a name="line.850"></a>
-<span class="sourceLineNo">851</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    }<a name="line.852"></a>
-<span class="sourceLineNo">853</span><a name="line.853"></a>
-<span class="sourceLineNo">854</span>    @Override<a name="line.854"></a>
-<span class="sourceLineNo">855</span>    public void abort(String why, Throwable e) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    public boolean isAborted() {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      return false;<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>    @Override<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    public void stop(String why) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    }<a name="line.867"></a>
-<span class="sourceLineNo">868</span><a name="line.868"></a>
-<span class="sourceLineNo">869</span>    @Override<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    public boolean isStopped() {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    public ChoreService getChoreService() {<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      return null;<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    }<a name="line.877"></a>
-<span class="sourceLineNo">878</span><a name="line.878"></a>
-<span class="sourceLineNo">879</span>    @Override<a name="line.879"></a>
-<span class="sourceLineNo">880</span>    public ClusterConnection getClusterConnection() {<a name="line.880"></a>
-<span class="sourceLineNo">881</span>      // TODO Auto-generated method stub<a name="line.881"></a>
-<span class="sourceLineNo">882</span>      return null;<a name="line.882"></a>
+<span class="sourceLineNo">830</span>  static class DummyServer implements Server {<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    String hostname;<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>    DummyServer() {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>      hostname = "hostname.example.org";<a name="line.834"></a>
+<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
+<span class="sourceLineNo">836</span><a name="line.836"></a>
+<span class="sourceLineNo">837</span>    DummyServer(String hostname) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      this.hostname = hostname;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>    @Override<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    public Configuration getConfiguration() {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      return conf;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>    }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>    @Override<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    public ZKWatcher getZooKeeper() {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      return zkw;<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span><a name="line.850"></a>
+<span class="sourceLineNo">851</span>    @Override<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>      return null;<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    }<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    @Override<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    public ClusterConnection getConnection() {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      return null;<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>    @Override<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      return null;<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    }<a name="line.863"></a>
+<span class="sourceLineNo">864</span><a name="line.864"></a>
+<span class="sourceLineNo">865</span>    @Override<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    public ServerName getServerName() {<a name="line.866"></a>
+<span class="sourceLineNo">867</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    }<a name="line.868"></a>
+<span class="sourceLineNo">869</span><a name="line.869"></a>
+<span class="sourceLineNo">870</span>    @Override<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    public void abort(String why, Throwable e) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.872"></a>
+<span class="sourceLineNo">873</span>    }<a name="line.873"></a>
+<span class="sourceLineNo">874</span><a name="line.874"></a>
+<span class="sourceLineNo">875</span>    @Override<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    public boolean isAborted() {<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      return false;<a name="line.877"></a>
+<span class="sourceLineNo">878</span>    }<a name="line.878"></a>
+<span class="sourceLineNo">879</span><a name="line.879"></a>
+<span class="sourceLineNo">880</span>    @Override<a name="line.880"></a>
+<span class="sourceLineNo">881</span>    public void stop(String why) {<a name="line.881"></a>
+<span class="sourceLineNo">882</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.882"></a>
 <span class="sourceLineNo">883</span>    }<a name="line.883"></a>
 <span class="sourceLineNo">884</span><a name="line.884"></a>
 <span class="sourceLineNo">885</span>    @Override<a name="line.885"></a>
-<span class="sourceLineNo">886</span>    public FileSystem getFileSystem() {<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return null;<a name="line.887"></a>
+<span class="sourceLineNo">886</span>    public boolean isStopped() {<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    public boolean isStopping() {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      return false;<a name="line.892"></a>
+<span class="sourceLineNo">891</span>    public ChoreService getChoreService() {<a name="line.891"></a>
+<span class="sourceLineNo">892</span>      return null;<a name="line.892"></a>
 <span class="sourceLineNo">893</span>    }<a name="line.893"></a>
 <span class="sourceLineNo">894</span><a name="line.894"></a>
 <span class="sourceLineNo">895</span>    @Override<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.896"></a>
-<span class="sourceLineNo">897</span>      return null;<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">896</span>    public ClusterConnection getClusterConnection() {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // TODO Auto-generated method stub<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      return null;<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>    @Override<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    public FileSystem getFileSystem() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>      return null;<a name="line.903"></a>
+<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>    @Override<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    public boolean isStopping() {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      return false;<a name="line.908"></a>
+<span class="sourceLineNo">909</span>    }<a name="line.909"></a>
+<span class="sourceLineNo">910</span><a name="line.910"></a>
+<span class="sourceLineNo">911</span>    @Override<a name="line.911"></a>
+<span class="sourceLineNo">912</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>      return null;<a name="line.913"></a>
+<span class="sourceLineNo">914</span>    }<a name="line.914"></a>
+<span class="sourceLineNo">915</span>  }<a name="line.915"></a>
+<span class="sourceLineNo">916</span>}<a name="line.916"></a>
 
 
 


[40/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
index 86fe2b3..4a6979a 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
@@ -215,9 +215,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/PeerProcedureInterface.PeerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">PeerProcedureInterface.PeerOperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/ServerProcedureInterface.ServerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">ServerProcedureInterface.ServerOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/PeerProcedureInterface.PeerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">PeerProcedureInterface.PeerOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">TableProcedureInterface.TableOperationType</span></a></li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
index 4b549da..7b435d2 100644
--- a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
@@ -127,8 +127,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/TaskMonitor.TaskFilter.TaskType.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">TaskMonitor.TaskFilter.TaskType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/TaskMonitor.TaskFilter.TaskType.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">TaskMonitor.TaskFilter.TaskType</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/package-tree.html b/devapidocs/org/apache/hadoop/hbase/package-tree.html
index 7bd4d55..73f1f8d 100644
--- a/devapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -437,19 +437,19 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaTableAccessor.QueryType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeepDeletedCells.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeepDeletedCells</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaTableAccessor.QueryType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterMetrics.Option</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
index a5289f9..21878a9 100644
--- a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
@@ -229,13 +229,13 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/OperationQuota.OperationType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">OperationQuota.OperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/ThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottlingException.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 89468d4..0df09d0 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -716,20 +716,20 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/Region.Operation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">Region.Operation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/SplitLogWorker.TaskExecutor.Status.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">SplitLogWorker.TaskExecutor.Status</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
index 23060c2..b377318 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
@@ -131,8 +131,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
 <li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/StripeCompactionScanQueryMatcher.DropDeletesInOutput.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">StripeCompactionScanQueryMatcher.DropDeletesInOutput</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/DeleteTracker.DeleteResult.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">DeleteTracker.DeleteResult</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/ScanQueryMatcher.MatchCode.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">ScanQueryMatcher.MatchCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/DeleteTracker.DeleteResult.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">DeleteTracker.DeleteResult</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
index 5dd2209..6783146 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
@@ -873,7 +873,7 @@ public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbas
 <ul class="blockList">
 <li class="blockList">
 <h4>extractHiddenEof</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html#line.428">extractHiddenEof</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;ex)</pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html#line.444">extractHiddenEof</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;ex)</pre>
 </li>
 </ul>
 <a name="seekOnFs-long-">
@@ -882,7 +882,7 @@ public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbas
 <ul class="blockListLast">
 <li class="blockList">
 <h4>seekOnFs</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html#line.448">seekOnFs</a>(long&nbsp;pos)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html#line.464">seekOnFs</a>(long&nbsp;pos)
                  throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ReaderBase.html#seekOnFs-long-">ReaderBase</a></code></span></div>
 <div class="block">Performs a filesystem-level seek to a certain position in an underlying file.</div>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
index 7eedc5c..46651a5 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
@@ -248,8 +248,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">ProtobufLogReader.WALHdrResult</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
index f8e4b11..3c7146a 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
@@ -160,8 +160,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/SyncReplicationState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">SyncReplicationState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/ReplicationPeer.PeerState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">ReplicationPeer.PeerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/SyncReplicationState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">SyncReplicationState</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
index e34cac6..93c6b74 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.834">ReplicationSourceManager.NodeFailoverWorker</a>
+<pre>class <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.825">ReplicationSourceManager.NodeFailoverWorker</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html?is-external=true" title="class or interface in java.lang">Thread</a></pre>
 <div class="block">Class responsible to setup new ReplicationSources to take care of the queues from dead region
  servers.</div>
@@ -250,7 +250,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>deadRS</h4>
-<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.836">deadRS</a></pre>
+<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.827">deadRS</a></pre>
 </li>
 </ul>
 <a name="peersSnapshot">
@@ -259,7 +259,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>peersSnapshot</h4>
-<pre>private final&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="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeerImpl.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeerImpl</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.844">peersSnapshot</a></pre>
+<pre>private final&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="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeerImpl.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeerImpl</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.835">peersSnapshot</a></pre>
 </li>
 </ul>
 </li>
@@ -276,7 +276,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>NodeFailoverWorker</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.847">NodeFailoverWorker</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;deadRS)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.838">NodeFailoverWorker</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;deadRS)</pre>
 </li>
 </ul>
 </li>
@@ -293,7 +293,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isOldPeer</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.853">isOldPeer</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;peerId,
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.844">isOldPeer</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;peerId,
                           <a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeerImpl.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeerImpl</a>&nbsp;newPeerRef)</pre>
 </li>
 </ul>
@@ -303,7 +303,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>run</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.859">run</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html#line.850">run</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html?is-external=true#run--" title="class or interface in java.lang">run</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html?is-external=true" title="class or interface in java.lang">Runnable</a></code></dd>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
index 4365151..6aec37e 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html?is-external=true" title="class or interface in java.lang">@FunctionalInterface</a>
-private static interface <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.566">ReplicationSourceManager.ReplicationQueueOperation</a></pre>
+private static interface <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.565">ReplicationSourceManager.ReplicationQueueOperation</a></pre>
 </li>
 </ul>
 </div>
@@ -154,7 +154,7 @@ private static interface <a href="../../../../../../src-html/org/apache/hadoop/h
 <ul class="blockListLast">
 <li class="blockList">
 <h4>exec</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html#line.567">exec</a>()
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html#line.566">exec</a>()
    throws <a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationException.html" title="class in org.apache.hadoop.hbase.replication">ReplicationException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>


[37/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
index a16d6c3..e11b36c 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html
@@ -295,193 +295,185 @@
 <span class="sourceLineNo">287</span>     */<a name="line.287"></a>
 <span class="sourceLineNo">288</span>    @Override<a name="line.288"></a>
 <span class="sourceLineNo">289</span>    public String getRegionNameAsString() {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      if (RegionInfo.hasEncodedName(this.regionName)) {<a name="line.290"></a>
-<span class="sourceLineNo">291</span>        // new format region names already have their encoded name.<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        return Bytes.toStringBinary(this.regionName);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span><a name="line.294"></a>
-<span class="sourceLineNo">295</span>      // old format. regionNameStr doesn't have the region name.<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      //<a name="line.296"></a>
-<span class="sourceLineNo">297</span>      //<a name="line.297"></a>
-<span class="sourceLineNo">298</span>      return Bytes.toStringBinary(this.regionName) + "." + this.getEncodedName();<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    }<a name="line.299"></a>
-<span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>    /** @return the encoded region name */<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    @Override<a name="line.302"></a>
-<span class="sourceLineNo">303</span>    public String getEncodedName() {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      return this.encodedName;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    @Override<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    public byte [] getEncodedNameAsBytes() {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>      return this.encodedNameAsBytes;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
-<span class="sourceLineNo">311</span><a name="line.311"></a>
-<span class="sourceLineNo">312</span>    /** @return the startKey */<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    @Override<a name="line.313"></a>
-<span class="sourceLineNo">314</span>    public byte [] getStartKey(){<a name="line.314"></a>
-<span class="sourceLineNo">315</span>      return startKey;<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    }<a name="line.316"></a>
-<span class="sourceLineNo">317</span><a name="line.317"></a>
-<span class="sourceLineNo">318</span><a name="line.318"></a>
-<span class="sourceLineNo">319</span>    /** @return the endKey */<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    @Override<a name="line.320"></a>
-<span class="sourceLineNo">321</span>    public byte [] getEndKey(){<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      return endKey;<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span><a name="line.324"></a>
-<span class="sourceLineNo">325</span>    /**<a name="line.325"></a>
-<span class="sourceLineNo">326</span>     * Get current table name of the region<a name="line.326"></a>
-<span class="sourceLineNo">327</span>     * @return TableName<a name="line.327"></a>
-<span class="sourceLineNo">328</span>     */<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    @Override<a name="line.329"></a>
-<span class="sourceLineNo">330</span>    public TableName getTable() {<a name="line.330"></a>
-<span class="sourceLineNo">331</span>      return this.tableName;<a name="line.331"></a>
-<span class="sourceLineNo">332</span>    }<a name="line.332"></a>
-<span class="sourceLineNo">333</span><a name="line.333"></a>
-<span class="sourceLineNo">334</span>    /**<a name="line.334"></a>
-<span class="sourceLineNo">335</span>     * Returns true if the given inclusive range of rows is fully contained<a name="line.335"></a>
-<span class="sourceLineNo">336</span>     * by this region. For example, if the region is foo,a,g and this is<a name="line.336"></a>
-<span class="sourceLineNo">337</span>     * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.337"></a>
-<span class="sourceLineNo">338</span>     * ["b","z"] it will return false.<a name="line.338"></a>
-<span class="sourceLineNo">339</span>     * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.339"></a>
-<span class="sourceLineNo">340</span>     */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>    @Override<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      if (Bytes.compareTo(rangeStartKey, rangeEndKey) &gt; 0) {<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        throw new IllegalArgumentException(<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        "Invalid range: " + Bytes.toStringBinary(rangeStartKey) +<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        " &gt; " + Bytes.toStringBinary(rangeEndKey));<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>      boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) &gt;= 0;<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      boolean lastKeyInRange =<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        Bytes.compareTo(rangeEndKey, endKey) &lt; 0 ||<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY);<a name="line.352"></a>
-<span class="sourceLineNo">353</span>      return firstKeyInRange &amp;&amp; lastKeyInRange;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    }<a name="line.354"></a>
-<span class="sourceLineNo">355</span><a name="line.355"></a>
-<span class="sourceLineNo">356</span>    /**<a name="line.356"></a>
-<span class="sourceLineNo">357</span>     * Return true if the given row falls in this region.<a name="line.357"></a>
-<span class="sourceLineNo">358</span>     */<a name="line.358"></a>
+<span class="sourceLineNo">290</span>      return RegionInfo.getRegionNameAsString(this, this.regionName);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>    }<a name="line.291"></a>
+<span class="sourceLineNo">292</span><a name="line.292"></a>
+<span class="sourceLineNo">293</span>    /** @return the encoded region name */<a name="line.293"></a>
+<span class="sourceLineNo">294</span>    @Override<a name="line.294"></a>
+<span class="sourceLineNo">295</span>    public String getEncodedName() {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      return this.encodedName;<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    }<a name="line.297"></a>
+<span class="sourceLineNo">298</span><a name="line.298"></a>
+<span class="sourceLineNo">299</span>    @Override<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    public byte [] getEncodedNameAsBytes() {<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      return this.encodedNameAsBytes;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
+<span class="sourceLineNo">303</span><a name="line.303"></a>
+<span class="sourceLineNo">304</span>    /** @return the startKey */<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    @Override<a name="line.305"></a>
+<span class="sourceLineNo">306</span>    public byte [] getStartKey(){<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return startKey;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span><a name="line.309"></a>
+<span class="sourceLineNo">310</span><a name="line.310"></a>
+<span class="sourceLineNo">311</span>    /** @return the endKey */<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    @Override<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    public byte [] getEndKey(){<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      return endKey;<a name="line.314"></a>
+<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>    /**<a name="line.317"></a>
+<span class="sourceLineNo">318</span>     * Get current table name of the region<a name="line.318"></a>
+<span class="sourceLineNo">319</span>     * @return TableName<a name="line.319"></a>
+<span class="sourceLineNo">320</span>     */<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    @Override<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    public TableName getTable() {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>      return this.tableName;<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span><a name="line.325"></a>
+<span class="sourceLineNo">326</span>    /**<a name="line.326"></a>
+<span class="sourceLineNo">327</span>     * Returns true if the given inclusive range of rows is fully contained<a name="line.327"></a>
+<span class="sourceLineNo">328</span>     * by this region. For example, if the region is foo,a,g and this is<a name="line.328"></a>
+<span class="sourceLineNo">329</span>     * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.329"></a>
+<span class="sourceLineNo">330</span>     * ["b","z"] it will return false.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>     * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.331"></a>
+<span class="sourceLineNo">332</span>     */<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    @Override<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      if (Bytes.compareTo(rangeStartKey, rangeEndKey) &gt; 0) {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>        throw new IllegalArgumentException(<a name="line.336"></a>
+<span class="sourceLineNo">337</span>        "Invalid range: " + Bytes.toStringBinary(rangeStartKey) +<a name="line.337"></a>
+<span class="sourceLineNo">338</span>        " &gt; " + Bytes.toStringBinary(rangeEndKey));<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      }<a name="line.339"></a>
+<span class="sourceLineNo">340</span><a name="line.340"></a>
+<span class="sourceLineNo">341</span>      boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) &gt;= 0;<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      boolean lastKeyInRange =<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        Bytes.compareTo(rangeEndKey, endKey) &lt; 0 ||<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      return firstKeyInRange &amp;&amp; lastKeyInRange;<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    /**<a name="line.348"></a>
+<span class="sourceLineNo">349</span>     * Return true if the given row falls in this region.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>     */<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    @Override<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    public boolean containsRow(byte[] row) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      return Bytes.compareTo(row, startKey) &gt;= 0 &amp;&amp;<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        (Bytes.compareTo(row, endKey) &lt; 0 ||<a name="line.354"></a>
+<span class="sourceLineNo">355</span>         Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY));<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    /** @return true if this region is a meta region */<a name="line.358"></a>
 <span class="sourceLineNo">359</span>    @Override<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    public boolean containsRow(byte[] row) {<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      return Bytes.compareTo(row, startKey) &gt;= 0 &amp;&amp;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        (Bytes.compareTo(row, endKey) &lt; 0 ||<a name="line.362"></a>
-<span class="sourceLineNo">363</span>         Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY));<a name="line.363"></a>
-<span class="sourceLineNo">364</span>    }<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    /** @return true if this region is a meta region */<a name="line.366"></a>
+<span class="sourceLineNo">360</span>    public boolean isMetaRegion() {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>       return tableName.equals(FIRST_META_REGIONINFO.getTable());<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    }<a name="line.362"></a>
+<span class="sourceLineNo">363</span><a name="line.363"></a>
+<span class="sourceLineNo">364</span>    /**<a name="line.364"></a>
+<span class="sourceLineNo">365</span>     * @return True if has been split and has daughters.<a name="line.365"></a>
+<span class="sourceLineNo">366</span>     */<a name="line.366"></a>
 <span class="sourceLineNo">367</span>    @Override<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    public boolean isMetaRegion() {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>       return tableName.equals(FIRST_META_REGIONINFO.getTable());<a name="line.369"></a>
+<span class="sourceLineNo">368</span>    public boolean isSplit() {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      return this.split;<a name="line.369"></a>
 <span class="sourceLineNo">370</span>    }<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>     * @return True if has been split and has daughters.<a name="line.373"></a>
-<span class="sourceLineNo">374</span>     */<a name="line.374"></a>
-<span class="sourceLineNo">375</span>    @Override<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    public boolean isSplit() {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>      return this.split;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    }<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    /**<a name="line.380"></a>
-<span class="sourceLineNo">381</span>     * @param split set split status<a name="line.381"></a>
-<span class="sourceLineNo">382</span>     * @return MutableRegionInfo<a name="line.382"></a>
+<span class="sourceLineNo">373</span>     * @param split set split status<a name="line.373"></a>
+<span class="sourceLineNo">374</span>     * @return MutableRegionInfo<a name="line.374"></a>
+<span class="sourceLineNo">375</span>     */<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    public MutableRegionInfo setSplit(boolean split) {<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      this.split = split;<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      return this;<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    }<a name="line.379"></a>
+<span class="sourceLineNo">380</span><a name="line.380"></a>
+<span class="sourceLineNo">381</span>    /**<a name="line.381"></a>
+<span class="sourceLineNo">382</span>     * @return True if this region is offline.<a name="line.382"></a>
 <span class="sourceLineNo">383</span>     */<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    public MutableRegionInfo setSplit(boolean split) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      this.split = split;<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      return this;<a name="line.386"></a>
+<span class="sourceLineNo">384</span>    @Override<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    public boolean isOffline() {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      return this.offLine;<a name="line.386"></a>
 <span class="sourceLineNo">387</span>    }<a name="line.387"></a>
 <span class="sourceLineNo">388</span><a name="line.388"></a>
 <span class="sourceLineNo">389</span>    /**<a name="line.389"></a>
-<span class="sourceLineNo">390</span>     * @return True if this region is offline.<a name="line.390"></a>
-<span class="sourceLineNo">391</span>     */<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    @Override<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    public boolean isOffline() {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      return this.offLine;<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span><a name="line.396"></a>
-<span class="sourceLineNo">397</span>    /**<a name="line.397"></a>
-<span class="sourceLineNo">398</span>     * The parent of a region split is offline while split daughters hold<a name="line.398"></a>
-<span class="sourceLineNo">399</span>     * references to the parent. Offlined regions are closed.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>     * @param offLine Set online/offline status.<a name="line.400"></a>
-<span class="sourceLineNo">401</span>     * @return MutableRegionInfo<a name="line.401"></a>
+<span class="sourceLineNo">390</span>     * The parent of a region split is offline while split daughters hold<a name="line.390"></a>
+<span class="sourceLineNo">391</span>     * references to the parent. Offlined regions are closed.<a name="line.391"></a>
+<span class="sourceLineNo">392</span>     * @param offLine Set online/offline status.<a name="line.392"></a>
+<span class="sourceLineNo">393</span>     * @return MutableRegionInfo<a name="line.393"></a>
+<span class="sourceLineNo">394</span>     */<a name="line.394"></a>
+<span class="sourceLineNo">395</span>    public MutableRegionInfo setOffline(boolean offLine) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      this.offLine = offLine;<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      return this;<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    /**<a name="line.400"></a>
+<span class="sourceLineNo">401</span>     * @return True if this is a split parent region.<a name="line.401"></a>
 <span class="sourceLineNo">402</span>     */<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    public MutableRegionInfo setOffline(boolean offLine) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      this.offLine = offLine;<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      return this;<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    /**<a name="line.408"></a>
-<span class="sourceLineNo">409</span>     * @return True if this is a split parent region.<a name="line.409"></a>
-<span class="sourceLineNo">410</span>     */<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    @Override<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    public boolean isSplitParent() {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      if (!isSplit()) return false;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (!isOffline()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>        LOG.warn("Region is split but NOT offline: " + getRegionNameAsString());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      }<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      return true;<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>    /**<a name="line.420"></a>
-<span class="sourceLineNo">421</span>     * Returns the region replica id<a name="line.421"></a>
-<span class="sourceLineNo">422</span>     * @return returns region replica id<a name="line.422"></a>
+<span class="sourceLineNo">403</span>    @Override<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    public boolean isSplitParent() {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      if (!isSplit()) return false;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      if (!isOffline()) {<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        LOG.warn("Region is split but NOT offline: " + getRegionNameAsString());<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      }<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      return true;<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    }<a name="line.410"></a>
+<span class="sourceLineNo">411</span><a name="line.411"></a>
+<span class="sourceLineNo">412</span>    /**<a name="line.412"></a>
+<span class="sourceLineNo">413</span>     * Returns the region replica id<a name="line.413"></a>
+<span class="sourceLineNo">414</span>     * @return returns region replica id<a name="line.414"></a>
+<span class="sourceLineNo">415</span>     */<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    @Override<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    public int getReplicaId() {<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      return replicaId;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    }<a name="line.419"></a>
+<span class="sourceLineNo">420</span><a name="line.420"></a>
+<span class="sourceLineNo">421</span>    /**<a name="line.421"></a>
+<span class="sourceLineNo">422</span>     * @see java.lang.Object#toString()<a name="line.422"></a>
 <span class="sourceLineNo">423</span>     */<a name="line.423"></a>
 <span class="sourceLineNo">424</span>    @Override<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    public int getReplicaId() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      return replicaId;<a name="line.426"></a>
-<span class="sourceLineNo">427</span>    }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>    /**<a name="line.429"></a>
-<span class="sourceLineNo">430</span>     * @see java.lang.Object#toString()<a name="line.430"></a>
-<span class="sourceLineNo">431</span>     */<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    @Override<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    public String toString() {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      return "{ENCODED =&gt; " + getEncodedName() + ", " +<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        HConstants.NAME + " =&gt; '" + Bytes.toStringBinary(this.regionName)<a name="line.435"></a>
-<span class="sourceLineNo">436</span>        + "', STARTKEY =&gt; '" +<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        Bytes.toStringBinary(this.startKey) + "', ENDKEY =&gt; '" +<a name="line.437"></a>
-<span class="sourceLineNo">438</span>        Bytes.toStringBinary(this.endKey) + "'" +<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        (isOffline()? ", OFFLINE =&gt; true": "") +<a name="line.439"></a>
-<span class="sourceLineNo">440</span>        (isSplit()? ", SPLIT =&gt; true": "") +<a name="line.440"></a>
-<span class="sourceLineNo">441</span>        ((replicaId &gt; 0)? ", REPLICA_ID =&gt; " + replicaId : "") + "}";<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    }<a name="line.442"></a>
-<span class="sourceLineNo">443</span><a name="line.443"></a>
-<span class="sourceLineNo">444</span>    /**<a name="line.444"></a>
-<span class="sourceLineNo">445</span>     * @param o<a name="line.445"></a>
-<span class="sourceLineNo">446</span>     * @see java.lang.Object#equals(java.lang.Object)<a name="line.446"></a>
-<span class="sourceLineNo">447</span>     */<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    @Override<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    public boolean equals(Object o) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>      if (this == o) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>        return true;<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      }<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      if (o == null) {<a name="line.453"></a>
-<span class="sourceLineNo">454</span>        return false;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      }<a name="line.455"></a>
-<span class="sourceLineNo">456</span>      if (!(o instanceof RegionInfo)) {<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        return false;<a name="line.457"></a>
-<span class="sourceLineNo">458</span>      }<a name="line.458"></a>
-<span class="sourceLineNo">459</span>      return this.compareTo((RegionInfo)o) == 0;<a name="line.459"></a>
+<span class="sourceLineNo">425</span>    public String toString() {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      return "{ENCODED =&gt; " + getEncodedName() + ", " +<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        HConstants.NAME + " =&gt; '" + Bytes.toStringBinary(this.regionName)<a name="line.427"></a>
+<span class="sourceLineNo">428</span>        + "', STARTKEY =&gt; '" +<a name="line.428"></a>
+<span class="sourceLineNo">429</span>        Bytes.toStringBinary(this.startKey) + "', ENDKEY =&gt; '" +<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        Bytes.toStringBinary(this.endKey) + "'" +<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        (isOffline()? ", OFFLINE =&gt; true": "") +<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        (isSplit()? ", SPLIT =&gt; true": "") +<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        ((replicaId &gt; 0)? ", REPLICA_ID =&gt; " + replicaId : "") + "}";<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
+<span class="sourceLineNo">435</span><a name="line.435"></a>
+<span class="sourceLineNo">436</span>    /**<a name="line.436"></a>
+<span class="sourceLineNo">437</span>     * @param o<a name="line.437"></a>
+<span class="sourceLineNo">438</span>     * @see java.lang.Object#equals(java.lang.Object)<a name="line.438"></a>
+<span class="sourceLineNo">439</span>     */<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    @Override<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    public boolean equals(Object o) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      if (this == o) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        return true;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>      }<a name="line.444"></a>
+<span class="sourceLineNo">445</span>      if (o == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        return false;<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      if (!(o instanceof RegionInfo)) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>        return false;<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      }<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      return this.compareTo((RegionInfo)o) == 0;<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    }<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>     * @see java.lang.Object#hashCode()<a name="line.455"></a>
+<span class="sourceLineNo">456</span>     */<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    @Override<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    public int hashCode() {<a name="line.458"></a>
+<span class="sourceLineNo">459</span>      return this.hashCode;<a name="line.459"></a>
 <span class="sourceLineNo">460</span>    }<a name="line.460"></a>
 <span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>    /**<a name="line.462"></a>
-<span class="sourceLineNo">463</span>     * @see java.lang.Object#hashCode()<a name="line.463"></a>
-<span class="sourceLineNo">464</span>     */<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    @Override<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    public int hashCode() {<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      return this.hashCode;<a name="line.467"></a>
-<span class="sourceLineNo">468</span>    }<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>    @Override<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    public int compareTo(RegionInfo other) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>      return RegionInfo.COMPARATOR.compare(this, other);<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>  }<a name="line.475"></a>
-<span class="sourceLineNo">476</span>}<a name="line.476"></a>
+<span class="sourceLineNo">462</span>    @Override<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    public int compareTo(RegionInfo other) {<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      return RegionInfo.COMPARATOR.compare(this, other);<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
+<span class="sourceLineNo">468</span>}<a name="line.468"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.html b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.html
index a16d6c3..e11b36c 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfoBuilder.html
@@ -295,193 +295,185 @@
 <span class="sourceLineNo">287</span>     */<a name="line.287"></a>
 <span class="sourceLineNo">288</span>    @Override<a name="line.288"></a>
 <span class="sourceLineNo">289</span>    public String getRegionNameAsString() {<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      if (RegionInfo.hasEncodedName(this.regionName)) {<a name="line.290"></a>
-<span class="sourceLineNo">291</span>        // new format region names already have their encoded name.<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        return Bytes.toStringBinary(this.regionName);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span><a name="line.294"></a>
-<span class="sourceLineNo">295</span>      // old format. regionNameStr doesn't have the region name.<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      //<a name="line.296"></a>
-<span class="sourceLineNo">297</span>      //<a name="line.297"></a>
-<span class="sourceLineNo">298</span>      return Bytes.toStringBinary(this.regionName) + "." + this.getEncodedName();<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    }<a name="line.299"></a>
-<span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>    /** @return the encoded region name */<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    @Override<a name="line.302"></a>
-<span class="sourceLineNo">303</span>    public String getEncodedName() {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      return this.encodedName;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>    }<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    @Override<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    public byte [] getEncodedNameAsBytes() {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>      return this.encodedNameAsBytes;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
-<span class="sourceLineNo">311</span><a name="line.311"></a>
-<span class="sourceLineNo">312</span>    /** @return the startKey */<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    @Override<a name="line.313"></a>
-<span class="sourceLineNo">314</span>    public byte [] getStartKey(){<a name="line.314"></a>
-<span class="sourceLineNo">315</span>      return startKey;<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    }<a name="line.316"></a>
-<span class="sourceLineNo">317</span><a name="line.317"></a>
-<span class="sourceLineNo">318</span><a name="line.318"></a>
-<span class="sourceLineNo">319</span>    /** @return the endKey */<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    @Override<a name="line.320"></a>
-<span class="sourceLineNo">321</span>    public byte [] getEndKey(){<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      return endKey;<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span><a name="line.324"></a>
-<span class="sourceLineNo">325</span>    /**<a name="line.325"></a>
-<span class="sourceLineNo">326</span>     * Get current table name of the region<a name="line.326"></a>
-<span class="sourceLineNo">327</span>     * @return TableName<a name="line.327"></a>
-<span class="sourceLineNo">328</span>     */<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    @Override<a name="line.329"></a>
-<span class="sourceLineNo">330</span>    public TableName getTable() {<a name="line.330"></a>
-<span class="sourceLineNo">331</span>      return this.tableName;<a name="line.331"></a>
-<span class="sourceLineNo">332</span>    }<a name="line.332"></a>
-<span class="sourceLineNo">333</span><a name="line.333"></a>
-<span class="sourceLineNo">334</span>    /**<a name="line.334"></a>
-<span class="sourceLineNo">335</span>     * Returns true if the given inclusive range of rows is fully contained<a name="line.335"></a>
-<span class="sourceLineNo">336</span>     * by this region. For example, if the region is foo,a,g and this is<a name="line.336"></a>
-<span class="sourceLineNo">337</span>     * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.337"></a>
-<span class="sourceLineNo">338</span>     * ["b","z"] it will return false.<a name="line.338"></a>
-<span class="sourceLineNo">339</span>     * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.339"></a>
-<span class="sourceLineNo">340</span>     */<a name="line.340"></a>
-<span class="sourceLineNo">341</span>    @Override<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      if (Bytes.compareTo(rangeStartKey, rangeEndKey) &gt; 0) {<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        throw new IllegalArgumentException(<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        "Invalid range: " + Bytes.toStringBinary(rangeStartKey) +<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        " &gt; " + Bytes.toStringBinary(rangeEndKey));<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>      boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) &gt;= 0;<a name="line.349"></a>
-<span class="sourceLineNo">350</span>      boolean lastKeyInRange =<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        Bytes.compareTo(rangeEndKey, endKey) &lt; 0 ||<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY);<a name="line.352"></a>
-<span class="sourceLineNo">353</span>      return firstKeyInRange &amp;&amp; lastKeyInRange;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    }<a name="line.354"></a>
-<span class="sourceLineNo">355</span><a name="line.355"></a>
-<span class="sourceLineNo">356</span>    /**<a name="line.356"></a>
-<span class="sourceLineNo">357</span>     * Return true if the given row falls in this region.<a name="line.357"></a>
-<span class="sourceLineNo">358</span>     */<a name="line.358"></a>
+<span class="sourceLineNo">290</span>      return RegionInfo.getRegionNameAsString(this, this.regionName);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>    }<a name="line.291"></a>
+<span class="sourceLineNo">292</span><a name="line.292"></a>
+<span class="sourceLineNo">293</span>    /** @return the encoded region name */<a name="line.293"></a>
+<span class="sourceLineNo">294</span>    @Override<a name="line.294"></a>
+<span class="sourceLineNo">295</span>    public String getEncodedName() {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      return this.encodedName;<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    }<a name="line.297"></a>
+<span class="sourceLineNo">298</span><a name="line.298"></a>
+<span class="sourceLineNo">299</span>    @Override<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    public byte [] getEncodedNameAsBytes() {<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      return this.encodedNameAsBytes;<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
+<span class="sourceLineNo">303</span><a name="line.303"></a>
+<span class="sourceLineNo">304</span>    /** @return the startKey */<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    @Override<a name="line.305"></a>
+<span class="sourceLineNo">306</span>    public byte [] getStartKey(){<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return startKey;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span><a name="line.309"></a>
+<span class="sourceLineNo">310</span><a name="line.310"></a>
+<span class="sourceLineNo">311</span>    /** @return the endKey */<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    @Override<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    public byte [] getEndKey(){<a name="line.313"></a>
+<span class="sourceLineNo">314</span>      return endKey;<a name="line.314"></a>
+<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>    /**<a name="line.317"></a>
+<span class="sourceLineNo">318</span>     * Get current table name of the region<a name="line.318"></a>
+<span class="sourceLineNo">319</span>     * @return TableName<a name="line.319"></a>
+<span class="sourceLineNo">320</span>     */<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    @Override<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    public TableName getTable() {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>      return this.tableName;<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
+<span class="sourceLineNo">325</span><a name="line.325"></a>
+<span class="sourceLineNo">326</span>    /**<a name="line.326"></a>
+<span class="sourceLineNo">327</span>     * Returns true if the given inclusive range of rows is fully contained<a name="line.327"></a>
+<span class="sourceLineNo">328</span>     * by this region. For example, if the region is foo,a,g and this is<a name="line.328"></a>
+<span class="sourceLineNo">329</span>     * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.329"></a>
+<span class="sourceLineNo">330</span>     * ["b","z"] it will return false.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>     * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.331"></a>
+<span class="sourceLineNo">332</span>     */<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    @Override<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      if (Bytes.compareTo(rangeStartKey, rangeEndKey) &gt; 0) {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>        throw new IllegalArgumentException(<a name="line.336"></a>
+<span class="sourceLineNo">337</span>        "Invalid range: " + Bytes.toStringBinary(rangeStartKey) +<a name="line.337"></a>
+<span class="sourceLineNo">338</span>        " &gt; " + Bytes.toStringBinary(rangeEndKey));<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      }<a name="line.339"></a>
+<span class="sourceLineNo">340</span><a name="line.340"></a>
+<span class="sourceLineNo">341</span>      boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) &gt;= 0;<a name="line.341"></a>
+<span class="sourceLineNo">342</span>      boolean lastKeyInRange =<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        Bytes.compareTo(rangeEndKey, endKey) &lt; 0 ||<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      return firstKeyInRange &amp;&amp; lastKeyInRange;<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    /**<a name="line.348"></a>
+<span class="sourceLineNo">349</span>     * Return true if the given row falls in this region.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>     */<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    @Override<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    public boolean containsRow(byte[] row) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      return Bytes.compareTo(row, startKey) &gt;= 0 &amp;&amp;<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        (Bytes.compareTo(row, endKey) &lt; 0 ||<a name="line.354"></a>
+<span class="sourceLineNo">355</span>         Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY));<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    /** @return true if this region is a meta region */<a name="line.358"></a>
 <span class="sourceLineNo">359</span>    @Override<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    public boolean containsRow(byte[] row) {<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      return Bytes.compareTo(row, startKey) &gt;= 0 &amp;&amp;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        (Bytes.compareTo(row, endKey) &lt; 0 ||<a name="line.362"></a>
-<span class="sourceLineNo">363</span>         Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY));<a name="line.363"></a>
-<span class="sourceLineNo">364</span>    }<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    /** @return true if this region is a meta region */<a name="line.366"></a>
+<span class="sourceLineNo">360</span>    public boolean isMetaRegion() {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>       return tableName.equals(FIRST_META_REGIONINFO.getTable());<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    }<a name="line.362"></a>
+<span class="sourceLineNo">363</span><a name="line.363"></a>
+<span class="sourceLineNo">364</span>    /**<a name="line.364"></a>
+<span class="sourceLineNo">365</span>     * @return True if has been split and has daughters.<a name="line.365"></a>
+<span class="sourceLineNo">366</span>     */<a name="line.366"></a>
 <span class="sourceLineNo">367</span>    @Override<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    public boolean isMetaRegion() {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>       return tableName.equals(FIRST_META_REGIONINFO.getTable());<a name="line.369"></a>
+<span class="sourceLineNo">368</span>    public boolean isSplit() {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      return this.split;<a name="line.369"></a>
 <span class="sourceLineNo">370</span>    }<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>     * @return True if has been split and has daughters.<a name="line.373"></a>
-<span class="sourceLineNo">374</span>     */<a name="line.374"></a>
-<span class="sourceLineNo">375</span>    @Override<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    public boolean isSplit() {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>      return this.split;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    }<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    /**<a name="line.380"></a>
-<span class="sourceLineNo">381</span>     * @param split set split status<a name="line.381"></a>
-<span class="sourceLineNo">382</span>     * @return MutableRegionInfo<a name="line.382"></a>
+<span class="sourceLineNo">373</span>     * @param split set split status<a name="line.373"></a>
+<span class="sourceLineNo">374</span>     * @return MutableRegionInfo<a name="line.374"></a>
+<span class="sourceLineNo">375</span>     */<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    public MutableRegionInfo setSplit(boolean split) {<a name="line.376"></a>
+<span class="sourceLineNo">377</span>      this.split = split;<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      return this;<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    }<a name="line.379"></a>
+<span class="sourceLineNo">380</span><a name="line.380"></a>
+<span class="sourceLineNo">381</span>    /**<a name="line.381"></a>
+<span class="sourceLineNo">382</span>     * @return True if this region is offline.<a name="line.382"></a>
 <span class="sourceLineNo">383</span>     */<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    public MutableRegionInfo setSplit(boolean split) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      this.split = split;<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      return this;<a name="line.386"></a>
+<span class="sourceLineNo">384</span>    @Override<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    public boolean isOffline() {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      return this.offLine;<a name="line.386"></a>
 <span class="sourceLineNo">387</span>    }<a name="line.387"></a>
 <span class="sourceLineNo">388</span><a name="line.388"></a>
 <span class="sourceLineNo">389</span>    /**<a name="line.389"></a>
-<span class="sourceLineNo">390</span>     * @return True if this region is offline.<a name="line.390"></a>
-<span class="sourceLineNo">391</span>     */<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    @Override<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    public boolean isOffline() {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      return this.offLine;<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span><a name="line.396"></a>
-<span class="sourceLineNo">397</span>    /**<a name="line.397"></a>
-<span class="sourceLineNo">398</span>     * The parent of a region split is offline while split daughters hold<a name="line.398"></a>
-<span class="sourceLineNo">399</span>     * references to the parent. Offlined regions are closed.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>     * @param offLine Set online/offline status.<a name="line.400"></a>
-<span class="sourceLineNo">401</span>     * @return MutableRegionInfo<a name="line.401"></a>
+<span class="sourceLineNo">390</span>     * The parent of a region split is offline while split daughters hold<a name="line.390"></a>
+<span class="sourceLineNo">391</span>     * references to the parent. Offlined regions are closed.<a name="line.391"></a>
+<span class="sourceLineNo">392</span>     * @param offLine Set online/offline status.<a name="line.392"></a>
+<span class="sourceLineNo">393</span>     * @return MutableRegionInfo<a name="line.393"></a>
+<span class="sourceLineNo">394</span>     */<a name="line.394"></a>
+<span class="sourceLineNo">395</span>    public MutableRegionInfo setOffline(boolean offLine) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      this.offLine = offLine;<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      return this;<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
+<span class="sourceLineNo">399</span><a name="line.399"></a>
+<span class="sourceLineNo">400</span>    /**<a name="line.400"></a>
+<span class="sourceLineNo">401</span>     * @return True if this is a split parent region.<a name="line.401"></a>
 <span class="sourceLineNo">402</span>     */<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    public MutableRegionInfo setOffline(boolean offLine) {<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      this.offLine = offLine;<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      return this;<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    }<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    /**<a name="line.408"></a>
-<span class="sourceLineNo">409</span>     * @return True if this is a split parent region.<a name="line.409"></a>
-<span class="sourceLineNo">410</span>     */<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    @Override<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    public boolean isSplitParent() {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      if (!isSplit()) return false;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      if (!isOffline()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>        LOG.warn("Region is split but NOT offline: " + getRegionNameAsString());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      }<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      return true;<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>    /**<a name="line.420"></a>
-<span class="sourceLineNo">421</span>     * Returns the region replica id<a name="line.421"></a>
-<span class="sourceLineNo">422</span>     * @return returns region replica id<a name="line.422"></a>
+<span class="sourceLineNo">403</span>    @Override<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    public boolean isSplitParent() {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      if (!isSplit()) return false;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      if (!isOffline()) {<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        LOG.warn("Region is split but NOT offline: " + getRegionNameAsString());<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      }<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      return true;<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    }<a name="line.410"></a>
+<span class="sourceLineNo">411</span><a name="line.411"></a>
+<span class="sourceLineNo">412</span>    /**<a name="line.412"></a>
+<span class="sourceLineNo">413</span>     * Returns the region replica id<a name="line.413"></a>
+<span class="sourceLineNo">414</span>     * @return returns region replica id<a name="line.414"></a>
+<span class="sourceLineNo">415</span>     */<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    @Override<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    public int getReplicaId() {<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      return replicaId;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    }<a name="line.419"></a>
+<span class="sourceLineNo">420</span><a name="line.420"></a>
+<span class="sourceLineNo">421</span>    /**<a name="line.421"></a>
+<span class="sourceLineNo">422</span>     * @see java.lang.Object#toString()<a name="line.422"></a>
 <span class="sourceLineNo">423</span>     */<a name="line.423"></a>
 <span class="sourceLineNo">424</span>    @Override<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    public int getReplicaId() {<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      return replicaId;<a name="line.426"></a>
-<span class="sourceLineNo">427</span>    }<a name="line.427"></a>
-<span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>    /**<a name="line.429"></a>
-<span class="sourceLineNo">430</span>     * @see java.lang.Object#toString()<a name="line.430"></a>
-<span class="sourceLineNo">431</span>     */<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    @Override<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    public String toString() {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      return "{ENCODED =&gt; " + getEncodedName() + ", " +<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        HConstants.NAME + " =&gt; '" + Bytes.toStringBinary(this.regionName)<a name="line.435"></a>
-<span class="sourceLineNo">436</span>        + "', STARTKEY =&gt; '" +<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        Bytes.toStringBinary(this.startKey) + "', ENDKEY =&gt; '" +<a name="line.437"></a>
-<span class="sourceLineNo">438</span>        Bytes.toStringBinary(this.endKey) + "'" +<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        (isOffline()? ", OFFLINE =&gt; true": "") +<a name="line.439"></a>
-<span class="sourceLineNo">440</span>        (isSplit()? ", SPLIT =&gt; true": "") +<a name="line.440"></a>
-<span class="sourceLineNo">441</span>        ((replicaId &gt; 0)? ", REPLICA_ID =&gt; " + replicaId : "") + "}";<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    }<a name="line.442"></a>
-<span class="sourceLineNo">443</span><a name="line.443"></a>
-<span class="sourceLineNo">444</span>    /**<a name="line.444"></a>
-<span class="sourceLineNo">445</span>     * @param o<a name="line.445"></a>
-<span class="sourceLineNo">446</span>     * @see java.lang.Object#equals(java.lang.Object)<a name="line.446"></a>
-<span class="sourceLineNo">447</span>     */<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    @Override<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    public boolean equals(Object o) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>      if (this == o) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>        return true;<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      }<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      if (o == null) {<a name="line.453"></a>
-<span class="sourceLineNo">454</span>        return false;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      }<a name="line.455"></a>
-<span class="sourceLineNo">456</span>      if (!(o instanceof RegionInfo)) {<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        return false;<a name="line.457"></a>
-<span class="sourceLineNo">458</span>      }<a name="line.458"></a>
-<span class="sourceLineNo">459</span>      return this.compareTo((RegionInfo)o) == 0;<a name="line.459"></a>
+<span class="sourceLineNo">425</span>    public String toString() {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      return "{ENCODED =&gt; " + getEncodedName() + ", " +<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        HConstants.NAME + " =&gt; '" + Bytes.toStringBinary(this.regionName)<a name="line.427"></a>
+<span class="sourceLineNo">428</span>        + "', STARTKEY =&gt; '" +<a name="line.428"></a>
+<span class="sourceLineNo">429</span>        Bytes.toStringBinary(this.startKey) + "', ENDKEY =&gt; '" +<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        Bytes.toStringBinary(this.endKey) + "'" +<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        (isOffline()? ", OFFLINE =&gt; true": "") +<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        (isSplit()? ", SPLIT =&gt; true": "") +<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        ((replicaId &gt; 0)? ", REPLICA_ID =&gt; " + replicaId : "") + "}";<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
+<span class="sourceLineNo">435</span><a name="line.435"></a>
+<span class="sourceLineNo">436</span>    /**<a name="line.436"></a>
+<span class="sourceLineNo">437</span>     * @param o<a name="line.437"></a>
+<span class="sourceLineNo">438</span>     * @see java.lang.Object#equals(java.lang.Object)<a name="line.438"></a>
+<span class="sourceLineNo">439</span>     */<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    @Override<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    public boolean equals(Object o) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      if (this == o) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        return true;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>      }<a name="line.444"></a>
+<span class="sourceLineNo">445</span>      if (o == null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        return false;<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      if (!(o instanceof RegionInfo)) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>        return false;<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      }<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      return this.compareTo((RegionInfo)o) == 0;<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    }<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>     * @see java.lang.Object#hashCode()<a name="line.455"></a>
+<span class="sourceLineNo">456</span>     */<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    @Override<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    public int hashCode() {<a name="line.458"></a>
+<span class="sourceLineNo">459</span>      return this.hashCode;<a name="line.459"></a>
 <span class="sourceLineNo">460</span>    }<a name="line.460"></a>
 <span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>    /**<a name="line.462"></a>
-<span class="sourceLineNo">463</span>     * @see java.lang.Object#hashCode()<a name="line.463"></a>
-<span class="sourceLineNo">464</span>     */<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    @Override<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    public int hashCode() {<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      return this.hashCode;<a name="line.467"></a>
-<span class="sourceLineNo">468</span>    }<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>    @Override<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    public int compareTo(RegionInfo other) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>      return RegionInfo.COMPARATOR.compare(this, other);<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>  }<a name="line.475"></a>
-<span class="sourceLineNo">476</span>}<a name="line.476"></a>
+<span class="sourceLineNo">462</span>    @Override<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    public int compareTo(RegionInfo other) {<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      return RegionInfo.COMPARATOR.compare(this, other);<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
+<span class="sourceLineNo">466</span><a name="line.466"></a>
+<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
+<span class="sourceLineNo">468</span>}<a name="line.468"></a>
 
 
 


[26/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.PrimaryRegionCountSkewCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<

<TRUNCATED>

[08/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmplImpl.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmplImpl.html b/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmplImpl.html
index 6ed9d13..52c02b0 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmplImpl.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmplImpl.html
@@ -80,11 +80,11 @@
 <span class="sourceLineNo">072</span>int numOfPages = (int) Math.ceil(numOfRITs * 1.0 / ritsPerPage);<a name="line.72"></a>
 <span class="sourceLineNo">073</span><a name="line.73"></a>
 <span class="sourceLineNo">074</span>      // 51, 5<a name="line.74"></a>
-<span class="sourceLineNo">075</span>      jamonWriter.write("&lt;section&gt;\n    &lt;h2&gt;&lt;a name=\"rit\"&gt;Regions in Transition&lt;/a&gt;&lt;/h2&gt;\n     &lt;p&gt;");<a name="line.75"></a>
-<span class="sourceLineNo">076</span>      // 53, 9<a name="line.76"></a>
+<span class="sourceLineNo">075</span>      jamonWriter.write("&lt;section&gt;\n    &lt;h2&gt;&lt;a name=\"rit\"&gt;Regions in Transition&lt;/a&gt;&lt;/h2&gt;\n     &lt;p&gt;&lt;a href=\"/rits.jsp\"&gt;");<a name="line.75"></a>
+<span class="sourceLineNo">076</span>      // 53, 29<a name="line.76"></a>
 <span class="sourceLineNo">077</span>      org.jamon.escaping.Escaping.HTML.write(org.jamon.emit.StandardEmitter.valueOf(numOfRITs), jamonWriter);<a name="line.77"></a>
-<span class="sourceLineNo">078</span>      // 53, 24<a name="line.78"></a>
-<span class="sourceLineNo">079</span>      jamonWriter.write(" region(s) in transition.\n     ");<a name="line.79"></a>
+<span class="sourceLineNo">078</span>      // 53, 44<a name="line.78"></a>
+<span class="sourceLineNo">079</span>      jamonWriter.write(" region(s) in transition.&lt;/a&gt;\n     ");<a name="line.79"></a>
 <span class="sourceLineNo">080</span>      // 54, 6<a name="line.80"></a>
 <span class="sourceLineNo">081</span>      if (ritStat.hasRegionsTwiceOverThreshold()  )<a name="line.81"></a>
 <span class="sourceLineNo">082</span>      {<a name="line.82"></a>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmplImpl.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmplImpl.html b/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmplImpl.html
index 8f7ff31..3b11445 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmplImpl.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/tmpl/master/MasterStatusTmplImpl.html
@@ -316,109 +316,109 @@
 <span class="sourceLineNo">308</span>      // 217, 15<a name="line.308"></a>
 <span class="sourceLineNo">309</span>      jamonWriter.write("\n        ");<a name="line.309"></a>
 <span class="sourceLineNo">310</span>      // 218, 9<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      if (master.getMasterCoprocessorHost().findCoprocessor("RSGroupAdminEndpoint") != null )<a name="line.311"></a>
+<span class="sourceLineNo">311</span>      if (master.getAssignmentManager() != null )<a name="line.311"></a>
 <span class="sourceLineNo">312</span>      {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>        // 218, 98<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        jamonWriter.write("\n          &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"rsgroup\"&gt;RSGroup&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>        // 221, 13<a name="line.315"></a>
+<span class="sourceLineNo">313</span>        // 218, 54<a name="line.313"></a>
+<span class="sourceLineNo">314</span>        jamonWriter.write("\n          ");<a name="line.314"></a>
+<span class="sourceLineNo">315</span>        // 219, 11<a name="line.315"></a>
 <span class="sourceLineNo">316</span>        {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>          org.apache.hadoop.hbase.tmpl.master.RSGroupListTmpl __jamon__var_1 = new org.apache.hadoop.hbase.tmpl.master.RSGroupListTmpl(this.getTemplateManager());<a name="line.317"></a>
-<span class="sourceLineNo">318</span>          __jamon__var_1.renderNoFlush(jamonWriter, master, serverManager);<a name="line.318"></a>
+<span class="sourceLineNo">317</span>          org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl __jamon__var_1 = new org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl(this.getTemplateManager());<a name="line.317"></a>
+<span class="sourceLineNo">318</span>          __jamon__var_1.renderNoFlush(jamonWriter, master.getAssignmentManager());<a name="line.318"></a>
 <span class="sourceLineNo">319</span>        }<a name="line.319"></a>
-<span class="sourceLineNo">320</span>        // 221, 79<a name="line.320"></a>
-<span class="sourceLineNo">321</span>        jamonWriter.write("\n          &lt;/section&gt;\n        ");<a name="line.321"></a>
+<span class="sourceLineNo">320</span>        // 219, 92<a name="line.320"></a>
+<span class="sourceLineNo">321</span>        jamonWriter.write("\n        ");<a name="line.321"></a>
 <span class="sourceLineNo">322</span>      }<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      // 223, 15<a name="line.323"></a>
-<span class="sourceLineNo">324</span>      jamonWriter.write("\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"regionservers\"&gt;Region Servers&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.324"></a>
-<span class="sourceLineNo">325</span>      // 226, 13<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      {<a name="line.326"></a>
-<span class="sourceLineNo">327</span>        org.apache.hadoop.hbase.tmpl.master.RegionServerListTmpl __jamon__var_2 = new org.apache.hadoop.hbase.tmpl.master.RegionServerListTmpl(this.getTemplateManager());<a name="line.327"></a>
-<span class="sourceLineNo">328</span>        __jamon__var_2.setServers(servers );<a name="line.328"></a>
-<span class="sourceLineNo">329</span>        __jamon__var_2.renderNoFlush(jamonWriter, master);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      }<a name="line.330"></a>
-<span class="sourceLineNo">331</span>      // 226, 74<a name="line.331"></a>
-<span class="sourceLineNo">332</span>      jamonWriter.write("\n\n            ");<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      // 228, 13<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      if ((deadServers != null) )<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>        // 228, 42<a name="line.336"></a>
-<span class="sourceLineNo">337</span>        jamonWriter.write("\n                ");<a name="line.337"></a>
-<span class="sourceLineNo">338</span>        // 229, 17<a name="line.338"></a>
-<span class="sourceLineNo">339</span>        {<a name="line.339"></a>
-<span class="sourceLineNo">340</span>          // 229, 17<a name="line.340"></a>
-<span class="sourceLineNo">341</span>          __jamon_innerUnit__deadRegionServers(jamonWriter);<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        }<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        // 229, 40<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        jamonWriter.write("\n            ");<a name="line.344"></a>
+<span class="sourceLineNo">323</span>      // 220, 15<a name="line.323"></a>
+<span class="sourceLineNo">324</span>      jamonWriter.write("\n        ");<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      // 221, 9<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      if (master.getMasterCoprocessorHost().findCoprocessor("RSGroupAdminEndpoint") != null )<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      {<a name="line.327"></a>
+<span class="sourceLineNo">328</span>        // 221, 98<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        jamonWriter.write("\n          &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"rsgroup\"&gt;RSGroup&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        // 224, 13<a name="line.330"></a>
+<span class="sourceLineNo">331</span>        {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>          org.apache.hadoop.hbase.tmpl.master.RSGroupListTmpl __jamon__var_2 = new org.apache.hadoop.hbase.tmpl.master.RSGroupListTmpl(this.getTemplateManager());<a name="line.332"></a>
+<span class="sourceLineNo">333</span>          __jamon__var_2.renderNoFlush(jamonWriter, master, serverManager);<a name="line.333"></a>
+<span class="sourceLineNo">334</span>        }<a name="line.334"></a>
+<span class="sourceLineNo">335</span>        // 224, 79<a name="line.335"></a>
+<span class="sourceLineNo">336</span>        jamonWriter.write("\n          &lt;/section&gt;\n        ");<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      }<a name="line.337"></a>
+<span class="sourceLineNo">338</span>      // 226, 15<a name="line.338"></a>
+<span class="sourceLineNo">339</span>      jamonWriter.write("\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"regionservers\"&gt;Region Servers&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.339"></a>
+<span class="sourceLineNo">340</span>      // 229, 13<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        org.apache.hadoop.hbase.tmpl.master.RegionServerListTmpl __jamon__var_3 = new org.apache.hadoop.hbase.tmpl.master.RegionServerListTmpl(this.getTemplateManager());<a name="line.342"></a>
+<span class="sourceLineNo">343</span>        __jamon__var_3.setServers(servers );<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        __jamon__var_3.renderNoFlush(jamonWriter, master);<a name="line.344"></a>
 <span class="sourceLineNo">345</span>      }<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      // 230, 19<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      jamonWriter.write("\n        &lt;/section&gt;\n        &lt;section&gt;\n            ");<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      // 233, 13<a name="line.348"></a>
-<span class="sourceLineNo">349</span>      {<a name="line.349"></a>
-<span class="sourceLineNo">350</span>        org.apache.hadoop.hbase.tmpl.master.BackupMasterStatusTmpl __jamon__var_3 = new org.apache.hadoop.hbase.tmpl.master.BackupMasterStatusTmpl(this.getTemplateManager());<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        __jamon__var_3.renderNoFlush(jamonWriter, master );<a name="line.351"></a>
-<span class="sourceLineNo">352</span>      }<a name="line.352"></a>
-<span class="sourceLineNo">353</span>      // 233, 58<a name="line.353"></a>
-<span class="sourceLineNo">354</span>      jamonWriter.write("\n        &lt;/section&gt;\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"tables\"&gt;Tables&lt;/a&gt;&lt;/h2&gt;\n            &lt;div class=\"tabbable\"&gt;\n                &lt;ul class=\"nav nav-pills\"&gt;\n                    &lt;li class=\"active\"&gt;\n                        &lt;a href=\"#tab_userTables\" data-toggle=\"tab\"&gt;User Tables&lt;/a&gt;\n                    &lt;/li&gt;\n                    &lt;li class=\"\"&gt;\n                        &lt;a href=\"#tab_catalogTables\" data-toggle=\"tab\"&gt;System Tables&lt;/a&gt;\n                    &lt;/li&gt;\n                    &lt;li class=\"\"&gt;\n                        &lt;a href=\"#tab_userSnapshots\" data-toggle=\"tab\"&gt;Snapshots&lt;/a&gt;\n                    &lt;/li&gt;\n                &lt;/ul&gt;\n                &lt;div class=\"tab-content\" style=\"padding-bottom: 9px; border-bottom: 1px solid #ddd;\"&gt;\n                    &lt;d
 iv class=\"tab-pane active\" id=\"tab_userTables\"&gt;\n                        ");<a name="line.354"></a>
-<span class="sourceLineNo">355</span>      // 251, 25<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      if ((metaLocation != null) )<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      {<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        // 251, 55<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        jamonWriter.write("\n                            ");<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        // 252, 29<a name="line.360"></a>
-<span class="sourceLineNo">361</span>        {<a name="line.361"></a>
-<span class="sourceLineNo">362</span>          // 252, 29<a name="line.362"></a>
-<span class="sourceLineNo">363</span>          __jamon_innerUnit__userTables(jamonWriter);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        }<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        // 252, 45<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        jamonWriter.write("\n                        ");<a name="line.366"></a>
+<span class="sourceLineNo">346</span>      // 229, 74<a name="line.346"></a>
+<span class="sourceLineNo">347</span>      jamonWriter.write("\n\n            ");<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      // 231, 13<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      if ((deadServers != null) )<a name="line.349"></a>
+<span class="sourceLineNo">350</span>      {<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        // 231, 42<a name="line.351"></a>
+<span class="sourceLineNo">352</span>        jamonWriter.write("\n                ");<a name="line.352"></a>
+<span class="sourceLineNo">353</span>        // 232, 17<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>          // 232, 17<a name="line.355"></a>
+<span class="sourceLineNo">356</span>          __jamon_innerUnit__deadRegionServers(jamonWriter);<a name="line.356"></a>
+<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
+<span class="sourceLineNo">358</span>        // 232, 40<a name="line.358"></a>
+<span class="sourceLineNo">359</span>        jamonWriter.write("\n            ");<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      }<a name="line.360"></a>
+<span class="sourceLineNo">361</span>      // 233, 19<a name="line.361"></a>
+<span class="sourceLineNo">362</span>      jamonWriter.write("\n        &lt;/section&gt;\n        &lt;section&gt;\n            ");<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      // 236, 13<a name="line.363"></a>
+<span class="sourceLineNo">364</span>      {<a name="line.364"></a>
+<span class="sourceLineNo">365</span>        org.apache.hadoop.hbase.tmpl.master.BackupMasterStatusTmpl __jamon__var_4 = new org.apache.hadoop.hbase.tmpl.master.BackupMasterStatusTmpl(this.getTemplateManager());<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        __jamon__var_4.renderNoFlush(jamonWriter, master );<a name="line.366"></a>
 <span class="sourceLineNo">367</span>      }<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      // 253, 31<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                    &lt;div class=\"tab-pane\" id=\"tab_catalogTables\"&gt;\n                        ");<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      // 256, 25<a name="line.370"></a>
+<span class="sourceLineNo">368</span>      // 236, 58<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      jamonWriter.write("\n        &lt;/section&gt;\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"tables\"&gt;Tables&lt;/a&gt;&lt;/h2&gt;\n            &lt;div class=\"tabbable\"&gt;\n                &lt;ul class=\"nav nav-pills\"&gt;\n                    &lt;li class=\"active\"&gt;\n                        &lt;a href=\"#tab_userTables\" data-toggle=\"tab\"&gt;User Tables&lt;/a&gt;\n                    &lt;/li&gt;\n                    &lt;li class=\"\"&gt;\n                        &lt;a href=\"#tab_catalogTables\" data-toggle=\"tab\"&gt;System Tables&lt;/a&gt;\n                    &lt;/li&gt;\n                    &lt;li class=\"\"&gt;\n                        &lt;a href=\"#tab_userSnapshots\" data-toggle=\"tab\"&gt;Snapshots&lt;/a&gt;\n                    &lt;/li&gt;\n                &lt;/ul&gt;\n                &lt;div class=\"tab-content\" style=\"padding-bottom: 9px; border-bottom: 1px solid #ddd;\"&gt;\n                    &lt;d
 iv class=\"tab-pane active\" id=\"tab_userTables\"&gt;\n                        ");<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      // 254, 25<a name="line.370"></a>
 <span class="sourceLineNo">371</span>      if ((metaLocation != null) )<a name="line.371"></a>
 <span class="sourceLineNo">372</span>      {<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        // 256, 55<a name="line.373"></a>
+<span class="sourceLineNo">373</span>        // 254, 55<a name="line.373"></a>
 <span class="sourceLineNo">374</span>        jamonWriter.write("\n                            ");<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        // 257, 29<a name="line.375"></a>
+<span class="sourceLineNo">375</span>        // 255, 29<a name="line.375"></a>
 <span class="sourceLineNo">376</span>        {<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          // 257, 29<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          __jamon_innerUnit__catalogTables(jamonWriter);<a name="line.378"></a>
+<span class="sourceLineNo">377</span>          // 255, 29<a name="line.377"></a>
+<span class="sourceLineNo">378</span>          __jamon_innerUnit__userTables(jamonWriter);<a name="line.378"></a>
 <span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>        // 257, 48<a name="line.380"></a>
+<span class="sourceLineNo">380</span>        // 255, 45<a name="line.380"></a>
 <span class="sourceLineNo">381</span>        jamonWriter.write("\n                        ");<a name="line.381"></a>
 <span class="sourceLineNo">382</span>      }<a name="line.382"></a>
-<span class="sourceLineNo">383</span>      // 258, 31<a name="line.383"></a>
-<span class="sourceLineNo">384</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                    &lt;div class=\"tab-pane\" id=\"tab_userSnapshots\"&gt;\n                        ");<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      // 261, 25<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      {<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        // 261, 25<a name="line.387"></a>
-<span class="sourceLineNo">388</span>        __jamon_innerUnit__userSnapshots(jamonWriter);<a name="line.388"></a>
-<span class="sourceLineNo">389</span>      }<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      // 261, 44<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                &lt;/div&gt;\n            &lt;/div&gt;\n        &lt;/section&gt;\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"peers\"&gt;Peers&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.391"></a>
-<span class="sourceLineNo">392</span>      // 268, 13<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        // 268, 13<a name="line.394"></a>
-<span class="sourceLineNo">395</span>        __jamon_innerUnit__peerConfigs(jamonWriter);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      }<a name="line.396"></a>
-<span class="sourceLineNo">397</span>      // 268, 30<a name="line.397"></a>
-<span class="sourceLineNo">398</span>      jamonWriter.write("\n        &lt;/section&gt;\n        ");<a name="line.398"></a>
-<span class="sourceLineNo">399</span>      // 270, 9<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      if (master.getAssignmentManager() != null )<a name="line.400"></a>
+<span class="sourceLineNo">383</span>      // 256, 31<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                    &lt;div class=\"tab-pane\" id=\"tab_catalogTables\"&gt;\n                        ");<a name="line.384"></a>
+<span class="sourceLineNo">385</span>      // 259, 25<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      if ((metaLocation != null) )<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        // 259, 55<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        jamonWriter.write("\n                            ");<a name="line.389"></a>
+<span class="sourceLineNo">390</span>        // 260, 29<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        {<a name="line.391"></a>
+<span class="sourceLineNo">392</span>          // 260, 29<a name="line.392"></a>
+<span class="sourceLineNo">393</span>          __jamon_innerUnit__catalogTables(jamonWriter);<a name="line.393"></a>
+<span class="sourceLineNo">394</span>        }<a name="line.394"></a>
+<span class="sourceLineNo">395</span>        // 260, 48<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        jamonWriter.write("\n                        ");<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      }<a name="line.397"></a>
+<span class="sourceLineNo">398</span>      // 261, 31<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                    &lt;div class=\"tab-pane\" id=\"tab_userSnapshots\"&gt;\n                        ");<a name="line.399"></a>
+<span class="sourceLineNo">400</span>      // 264, 25<a name="line.400"></a>
 <span class="sourceLineNo">401</span>      {<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        // 270, 54<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        jamonWriter.write("\n        ");<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        // 271, 9<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>          org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl __jamon__var_4 = new org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl(this.getTemplateManager());<a name="line.406"></a>
-<span class="sourceLineNo">407</span>          __jamon__var_4.renderNoFlush(jamonWriter, master.getAssignmentManager());<a name="line.407"></a>
-<span class="sourceLineNo">408</span>        }<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        // 271, 90<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        jamonWriter.write("\n        ");<a name="line.410"></a>
+<span class="sourceLineNo">402</span>        // 264, 25<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        __jamon_innerUnit__userSnapshots(jamonWriter);<a name="line.403"></a>
+<span class="sourceLineNo">404</span>      }<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      // 264, 44<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      jamonWriter.write("\n                    &lt;/div&gt;\n                &lt;/div&gt;\n            &lt;/div&gt;\n        &lt;/section&gt;\n        &lt;section&gt;\n            &lt;h2&gt;&lt;a name=\"peers\"&gt;Peers&lt;/a&gt;&lt;/h2&gt;\n            ");<a name="line.406"></a>
+<span class="sourceLineNo">407</span>      // 271, 13<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      {<a name="line.408"></a>
+<span class="sourceLineNo">409</span>        // 271, 13<a name="line.409"></a>
+<span class="sourceLineNo">410</span>        __jamon_innerUnit__peerConfigs(jamonWriter);<a name="line.410"></a>
 <span class="sourceLineNo">411</span>      }<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      // 272, 15<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      jamonWriter.write("\n\t");<a name="line.413"></a>
+<span class="sourceLineNo">412</span>      // 271, 30<a name="line.412"></a>
+<span class="sourceLineNo">413</span>      jamonWriter.write("\n        &lt;/section&gt;\n\t");<a name="line.413"></a>
 <span class="sourceLineNo">414</span>    }<a name="line.414"></a>
 <span class="sourceLineNo">415</span>    // 273, 2<a name="line.415"></a>
 <span class="sourceLineNo">416</span>    else<a name="line.416"></a>
@@ -943,53 +943,97 @@
 <span class="sourceLineNo">935</span>        // 536, 13<a name="line.935"></a>
 <span class="sourceLineNo">936</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(openRegionsCount), jamonWriter);<a name="line.936"></a>
 <span class="sourceLineNo">937</span>        // 536, 35<a name="line.937"></a>
-<span class="sourceLineNo">938</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.938"></a>
-<span class="sourceLineNo">939</span>        // 537, 13<a name="line.939"></a>
-<span class="sourceLineNo">940</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(openingRegionsCount), jamonWriter);<a name="line.940"></a>
-<span class="sourceLineNo">941</span>        // 537, 38<a name="line.941"></a>
-<span class="sourceLineNo">942</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.942"></a>
-<span class="sourceLineNo">943</span>        // 538, 13<a name="line.943"></a>
-<span class="sourceLineNo">944</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(closedRegionsCount), jamonWriter);<a name="line.944"></a>
-<span class="sourceLineNo">945</span>        // 538, 37<a name="line.945"></a>
-<span class="sourceLineNo">946</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.946"></a>
-<span class="sourceLineNo">947</span>        // 539, 13<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(closingRegionsCount), jamonWriter);<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        // 539, 38<a name="line.949"></a>
-<span class="sourceLineNo">950</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.950"></a>
-<span class="sourceLineNo">951</span>        // 540, 13<a name="line.951"></a>
-<span class="sourceLineNo">952</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(offlineRegionsCount), jamonWriter);<a name="line.952"></a>
-<span class="sourceLineNo">953</span>        // 540, 38<a name="line.953"></a>
-<span class="sourceLineNo">954</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.954"></a>
-<span class="sourceLineNo">955</span>        // 541, 13<a name="line.955"></a>
-<span class="sourceLineNo">956</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(failedRegionsCount), jamonWriter);<a name="line.956"></a>
-<span class="sourceLineNo">957</span>        // 541, 37<a name="line.957"></a>
-<span class="sourceLineNo">958</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.958"></a>
-<span class="sourceLineNo">959</span>        // 542, 13<a name="line.959"></a>
-<span class="sourceLineNo">960</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(splitRegionsCount), jamonWriter);<a name="line.960"></a>
-<span class="sourceLineNo">961</span>        // 542, 36<a name="line.961"></a>
-<span class="sourceLineNo">962</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.962"></a>
-<span class="sourceLineNo">963</span>        // 543, 13<a name="line.963"></a>
-<span class="sourceLineNo">964</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(otherRegionsCount), jamonWriter);<a name="line.964"></a>
-<span class="sourceLineNo">965</span>        // 543, 36<a name="line.965"></a>
-<span class="sourceLineNo">966</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.966"></a>
-<span class="sourceLineNo">967</span>        // 544, 13<a name="line.967"></a>
-<span class="sourceLineNo">968</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(htDesc.toStringCustomizedValues()), jamonWriter);<a name="line.968"></a>
-<span class="sourceLineNo">969</span>        // 544, 52<a name="line.969"></a>
-<span class="sourceLineNo">970</span>        jamonWriter.write("&lt;/td&gt;\n    &lt;/tr&gt;\n    ");<a name="line.970"></a>
-<span class="sourceLineNo">971</span>      }<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      // 546, 12<a name="line.972"></a>
-<span class="sourceLineNo">973</span>      jamonWriter.write("\n    &lt;p&gt;");<a name="line.973"></a>
-<span class="sourceLineNo">974</span>      // 547, 8<a name="line.974"></a>
-<span class="sourceLineNo">975</span>      org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(tables.size()), jamonWriter);<a name="line.975"></a>
-<span class="sourceLineNo">976</span>      // 547, 27<a name="line.976"></a>
-<span class="sourceLineNo">977</span>      jamonWriter.write(" table(s) in set. [&lt;a href=tablesDetailed.jsp&gt;Details&lt;/a&gt;]&lt;/p&gt;\n&lt;/tbody&gt;\n&lt;/table&gt;\n");<a name="line.977"></a>
-<span class="sourceLineNo">978</span>    }<a name="line.978"></a>
-<span class="sourceLineNo">979</span>    // 550, 7<a name="line.979"></a>
-<span class="sourceLineNo">980</span>    jamonWriter.write("\n");<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>}<a name="line.984"></a>
+<span class="sourceLineNo">938</span>        jamonWriter.write("&lt;/td&gt;\n        ");<a name="line.938"></a>
+<span class="sourceLineNo">939</span>        // 537, 9<a name="line.939"></a>
+<span class="sourceLineNo">940</span>        if ((openingRegionsCount &gt; 0) )<a name="line.940"></a>
+<span class="sourceLineNo">941</span>        {<a name="line.941"></a>
+<span class="sourceLineNo">942</span>          // 537, 42<a name="line.942"></a>
+<span class="sourceLineNo">943</span>          jamonWriter.write(" &lt;td&gt;&lt;a href=\"/rits.jsp?table=");<a name="line.943"></a>
+<span class="sourceLineNo">944</span>          // 537, 72<a name="line.944"></a>
+<span class="sourceLineNo">945</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(tableName.getNameAsString()), jamonWriter);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>          // 537, 105<a name="line.946"></a>
+<span class="sourceLineNo">947</span>          jamonWriter.write("&amp;state=OPENING\"&gt;");<a name="line.947"></a>
+<span class="sourceLineNo">948</span>          // 537, 121<a name="line.948"></a>
+<span class="sourceLineNo">949</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(openingRegionsCount), jamonWriter);<a name="line.949"></a>
+<span class="sourceLineNo">950</span>          // 537, 146<a name="line.950"></a>
+<span class="sourceLineNo">951</span>          jamonWriter.write("&lt;/td&gt; ");<a name="line.951"></a>
+<span class="sourceLineNo">952</span>        }<a name="line.952"></a>
+<span class="sourceLineNo">953</span>        // 537, 152<a name="line.953"></a>
+<span class="sourceLineNo">954</span>        else<a name="line.954"></a>
+<span class="sourceLineNo">955</span>        {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>          // 537, 159<a name="line.956"></a>
+<span class="sourceLineNo">957</span>          jamonWriter.write("&lt;td&gt;");<a name="line.957"></a>
+<span class="sourceLineNo">958</span>          // 537, 163<a name="line.958"></a>
+<span class="sourceLineNo">959</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(openingRegionsCount), jamonWriter);<a name="line.959"></a>
+<span class="sourceLineNo">960</span>          // 537, 188<a name="line.960"></a>
+<span class="sourceLineNo">961</span>          jamonWriter.write("&lt;/td&gt; ");<a name="line.961"></a>
+<span class="sourceLineNo">962</span>        }<a name="line.962"></a>
+<span class="sourceLineNo">963</span>        // 537, 200<a name="line.963"></a>
+<span class="sourceLineNo">964</span>        jamonWriter.write("\n        &lt;td&gt;");<a name="line.964"></a>
+<span class="sourceLineNo">965</span>        // 538, 13<a name="line.965"></a>
+<span class="sourceLineNo">966</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(closedRegionsCount), jamonWriter);<a name="line.966"></a>
+<span class="sourceLineNo">967</span>        // 538, 37<a name="line.967"></a>
+<span class="sourceLineNo">968</span>        jamonWriter.write("&lt;/td&gt;\n        ");<a name="line.968"></a>
+<span class="sourceLineNo">969</span>        // 539, 9<a name="line.969"></a>
+<span class="sourceLineNo">970</span>        if ((closingRegionsCount &gt; 0) )<a name="line.970"></a>
+<span class="sourceLineNo">971</span>        {<a name="line.971"></a>
+<span class="sourceLineNo">972</span>          // 539, 42<a name="line.972"></a>
+<span class="sourceLineNo">973</span>          jamonWriter.write(" &lt;td&gt;&lt;a href=\"/rits.jsp?table=");<a name="line.973"></a>
+<span class="sourceLineNo">974</span>          // 539, 72<a name="line.974"></a>
+<span class="sourceLineNo">975</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(tableName.getNameAsString()), jamonWriter);<a name="line.975"></a>
+<span class="sourceLineNo">976</span>          // 539, 105<a name="line.976"></a>
+<span class="sourceLineNo">977</span>          jamonWriter.write("&amp;state=CLOSING\"&gt;");<a name="line.977"></a>
+<span class="sourceLineNo">978</span>          // 539, 121<a name="line.978"></a>
+<span class="sourceLineNo">979</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(closingRegionsCount), jamonWriter);<a name="line.979"></a>
+<span class="sourceLineNo">980</span>          // 539, 146<a name="line.980"></a>
+<span class="sourceLineNo">981</span>          jamonWriter.write("&lt;/td&gt; ");<a name="line.981"></a>
+<span class="sourceLineNo">982</span>        }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>        // 539, 152<a name="line.983"></a>
+<span class="sourceLineNo">984</span>        else<a name="line.984"></a>
+<span class="sourceLineNo">985</span>        {<a name="line.985"></a>
+<span class="sourceLineNo">986</span>          // 539, 159<a name="line.986"></a>
+<span class="sourceLineNo">987</span>          jamonWriter.write("&lt;td&gt;");<a name="line.987"></a>
+<span class="sourceLineNo">988</span>          // 539, 163<a name="line.988"></a>
+<span class="sourceLineNo">989</span>          org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(closingRegionsCount), jamonWriter);<a name="line.989"></a>
+<span class="sourceLineNo">990</span>          // 539, 188<a name="line.990"></a>
+<span class="sourceLineNo">991</span>          jamonWriter.write("&lt;/td&gt; ");<a name="line.991"></a>
+<span class="sourceLineNo">992</span>        }<a name="line.992"></a>
+<span class="sourceLineNo">993</span>        // 539, 200<a name="line.993"></a>
+<span class="sourceLineNo">994</span>        jamonWriter.write("\n        &lt;td&gt;");<a name="line.994"></a>
+<span class="sourceLineNo">995</span>        // 540, 13<a name="line.995"></a>
+<span class="sourceLineNo">996</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(offlineRegionsCount), jamonWriter);<a name="line.996"></a>
+<span class="sourceLineNo">997</span>        // 540, 38<a name="line.997"></a>
+<span class="sourceLineNo">998</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.998"></a>
+<span class="sourceLineNo">999</span>        // 541, 13<a name="line.999"></a>
+<span class="sourceLineNo">1000</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(failedRegionsCount), jamonWriter);<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>        // 541, 37<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>        // 542, 13<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(splitRegionsCount), jamonWriter);<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>        // 542, 36<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>        // 543, 13<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(otherRegionsCount), jamonWriter);<a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>        // 543, 36<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>        jamonWriter.write("&lt;/td&gt;\n        &lt;td&gt;");<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>        // 544, 13<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>        org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(htDesc.toStringCustomizedValues()), jamonWriter);<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>        // 544, 52<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>        jamonWriter.write("&lt;/td&gt;\n    &lt;/tr&gt;\n    ");<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>      }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>      // 546, 12<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span>      jamonWriter.write("\n    &lt;p&gt;");<a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>      // 547, 8<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>      org.jamon.escaping.Escaping.NONE.write(org.jamon.emit.StandardEmitter.valueOf(tables.size()), jamonWriter);<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>      // 547, 27<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>      jamonWriter.write(" table(s) in set. [&lt;a href=tablesDetailed.jsp&gt;Details&lt;/a&gt;]&lt;/p&gt;\n&lt;/tbody&gt;\n&lt;/table&gt;\n");<a name="line.1021"></a>
+<span class="sourceLineNo">1022</span>    }<a name="line.1022"></a>
+<span class="sourceLineNo">1023</span>    // 550, 7<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>    jamonWriter.write("\n");<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  }<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>}<a name="line.1028"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/downloads.html
----------------------------------------------------------------------
diff --git a/downloads.html b/downloads.html
index 247c326..8f92eb6 100644
--- a/downloads.html
+++ b/downloads.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBase Downloads</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -461,7 +461,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/export_control.html
----------------------------------------------------------------------
diff --git a/export_control.html b/export_control.html
index 53c5ad4..fb43b1d 100644
--- a/export_control.html
+++ b/export_control.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Export Control
@@ -341,7 +341,7 @@ for more details.</p>
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/images/1-snapshot.png
----------------------------------------------------------------------
diff --git a/images/1-snapshot.png b/images/1-snapshot.png
new file mode 100644
index 0000000..a903902
Binary files /dev/null and b/images/1-snapshot.png differ

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/images/2-snapshots.png
----------------------------------------------------------------------
diff --git a/images/2-snapshots.png b/images/2-snapshots.png
new file mode 100644
index 0000000..2fd4574
Binary files /dev/null and b/images/2-snapshots.png differ

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/images/empty-snapshots.png
----------------------------------------------------------------------
diff --git a/images/empty-snapshots.png b/images/empty-snapshots.png
new file mode 100644
index 0000000..ce92e0f
Binary files /dev/null and b/images/empty-snapshots.png differ

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/images/master-snapshot.png
----------------------------------------------------------------------
diff --git a/images/master-snapshot.png b/images/master-snapshot.png
new file mode 100644
index 0000000..51ffc9a
Binary files /dev/null and b/images/master-snapshot.png differ

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/index.html
----------------------------------------------------------------------
diff --git a/index.html b/index.html
index 99cca23..87d7251 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBaseâ„¢ Home</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -421,7 +421,7 @@ Apache HBase is an open-source, distributed, versioned, non-relational database
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/integration.html
----------------------------------------------------------------------
diff --git a/integration.html b/integration.html
index fb23925..ec0c037 100644
--- a/integration.html
+++ b/integration.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; CI Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -301,7 +301,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/issue-tracking.html
----------------------------------------------------------------------
diff --git a/issue-tracking.html b/issue-tracking.html
index bdb600b..ef6a84b 100644
--- a/issue-tracking.html
+++ b/issue-tracking.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Issue Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -298,7 +298,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/license.html
----------------------------------------------------------------------
diff --git a/license.html b/license.html
index 36937fe..ff7d666 100644
--- a/license.html
+++ b/license.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Licenses</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -501,7 +501,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/mail-lists.html
----------------------------------------------------------------------
diff --git a/mail-lists.html b/mail-lists.html
index ade9b06..74de6b3 100644
--- a/mail-lists.html
+++ b/mail-lists.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Mailing Lists</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -351,7 +351,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/metrics.html
----------------------------------------------------------------------
diff --git a/metrics.html b/metrics.html
index 2ebf69e..6584319 100644
--- a/metrics.html
+++ b/metrics.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Apache HBase (TM) Metrics
@@ -469,7 +469,7 @@ export HBASE_REGIONSERVER_OPTS=&quot;$HBASE_JMX_OPTS -Dcom.sun.management.jmxrem
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/old_news.html
----------------------------------------------------------------------
diff --git a/old_news.html b/old_news.html
index e3571a8..4df4f31 100644
--- a/old_news.html
+++ b/old_news.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Old Apache HBase (TM) News
@@ -450,7 +450,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/plugin-management.html
----------------------------------------------------------------------
diff --git a/plugin-management.html b/plugin-management.html
index 60d89b8..c66e3ac 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Plugin Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -450,7 +450,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/plugins.html
----------------------------------------------------------------------
diff --git a/plugins.html b/plugins.html
index 7056ded..02af71a 100644
--- a/plugins.html
+++ b/plugins.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Plugins</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -381,7 +381,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/poweredbyhbase.html
----------------------------------------------------------------------
diff --git a/poweredbyhbase.html b/poweredbyhbase.html
index 086f3f7..e77127a 100644
--- a/poweredbyhbase.html
+++ b/poweredbyhbase.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Powered By Apache HBase™</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -779,7 +779,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/project-info.html
----------------------------------------------------------------------
diff --git a/project-info.html b/project-info.html
index d6f2443..f860a0d 100644
--- a/project-info.html
+++ b/project-info.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Information</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -345,7 +345,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/project-reports.html
----------------------------------------------------------------------
diff --git a/project-reports.html b/project-reports.html
index 0c150a2..4524c10 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Generated Reports</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -315,7 +315,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/project-summary.html
----------------------------------------------------------------------
diff --git a/project-summary.html b/project-summary.html
index a643785..00fc50b 100644
--- a/project-summary.html
+++ b/project-summary.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Summary</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -341,7 +341,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/pseudo-distributed.html
----------------------------------------------------------------------
diff --git a/pseudo-distributed.html b/pseudo-distributed.html
index 2be06a4..d33fad8 100644
--- a/pseudo-distributed.html
+++ b/pseudo-distributed.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
 Running Apache HBase (TM) in pseudo-distributed mode
@@ -318,7 +318,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/replication.html
----------------------------------------------------------------------
diff --git a/replication.html b/replication.html
index ce81b79..c6aea72 100644
--- a/replication.html
+++ b/replication.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Apache HBase (TM) Replication
@@ -313,7 +313,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/resources.html
----------------------------------------------------------------------
diff --git a/resources.html b/resources.html
index c5e532e..86d048d 100644
--- a/resources.html
+++ b/resources.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Other Apache HBase (TM) Resources</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -341,7 +341,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/source-repository.html
----------------------------------------------------------------------
diff --git a/source-repository.html b/source-repository.html
index 299764e..65f39d1 100644
--- a/source-repository.html
+++ b/source-repository.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Source Code Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -309,7 +309,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/sponsors.html
----------------------------------------------------------------------
diff --git a/sponsors.html b/sponsors.html
index cea1efd..f405cc9 100644
--- a/sponsors.html
+++ b/sponsors.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBase™ Sponsors</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -343,7 +343,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/supportingprojects.html
----------------------------------------------------------------------
diff --git a/supportingprojects.html b/supportingprojects.html
index 04a674f..1f523f1 100644
--- a/supportingprojects.html
+++ b/supportingprojects.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Supporting Projects</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -530,7 +530,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/team-list.html
----------------------------------------------------------------------
diff --git a/team-list.html b/team-list.html
index 0a66bca..aa6196b 100644
--- a/team-list.html
+++ b/team-list.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Team</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -770,7 +770,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/index-all.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/index-all.html b/testdevapidocs/index-all.html
index 783a2ba..c5e2ca4 100644
--- a/testdevapidocs/index-all.html
+++ b/testdevapidocs/index-all.html
@@ -61983,6 +61983,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/metrics/impl/TestFastLongHistogram.html#testSameValues--">testSameValues()</a></span> - Method in class org.apache.hadoop.hbase.metrics.impl.<a href="org/apache/hadoop/hbase/metrics/impl/TestFastLongHistogram.html" title="class in org.apache.hadoop.hbase.metrics.impl">TestFastLongHistogram</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html#testSameWALPrefix--">testSameWALPrefix()</a></span> - Method in class org.apache.hadoop.hbase.replication.regionserver.<a href="org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.html" title="class in org.apache.hadoop.hbase.replication.regionserver">TestReplicationSourceManager</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/mapreduce/TestMapReduceExamples.html#testSampleUploader--">testSampleUploader()</a></span> - Method in class org.apache.hadoop.hbase.mapreduce.<a href="org/apache/hadoop/hbase/mapreduce/TestMapReduceExamples.html" title="class in org.apache.hadoop.hbase.mapreduce">TestMapReduceExamples</a></dt>
 <dd>
 <div class="block">Test SampleUploader from examples</div>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
index 9500324..9271b6f 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.459">TestStochasticLoadBalancer.MockCluster</a>
+<pre>private class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.461">TestStochasticLoadBalancer.MockCluster</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>
 </li>
 </ul>
@@ -206,7 +206,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>localities</h4>
-<pre>private&nbsp;int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.461">localities</a></pre>
+<pre>private&nbsp;int[][] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.463">localities</a></pre>
 </li>
 </ul>
 </li>
@@ -223,7 +223,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>MockCluster</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.463">MockCluster</a>(int[][]&nbsp;regions)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.465">MockCluster</a>(int[][]&nbsp;regions)</pre>
 </li>
 </ul>
 </li>
@@ -240,7 +240,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLocalityOfRegion</h4>
-<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.481">getLocalityOfRegion</a>(int&nbsp;region,
+<pre>float&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.483">getLocalityOfRegion</a>(int&nbsp;region,
                           int&nbsp;server)</pre>
 </li>
 </ul>
@@ -250,7 +250,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRegionSizeMB</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.487">getRegionSizeMB</a>(int&nbsp;region)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.MockCluster.html#line.489">getRegionSizeMB</a>(int&nbsp;region)</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
index b02764c..16b3d6a 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html
@@ -408,7 +408,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testNeedBalance</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.238">testNeedBalance</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.240">testNeedBalance</a>()</pre>
 </li>
 </ul>
 <a name="testLocalityCost--">
@@ -417,7 +417,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testLocalityCost</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.253">testLocalityCost</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.255">testLocalityCost</a>()
                       throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -431,7 +431,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testMoveCost</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.270">testMoveCost</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.272">testMoveCost</a>()
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -445,7 +445,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testSkewCost</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.308">testSkewCost</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.310">testSkewCost</a>()</pre>
 </li>
 </ul>
 <a name="testCostAfterUndoAction--">
@@ -454,7 +454,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testCostAfterUndoAction</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.334">testCostAfterUndoAction</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.336">testCostAfterUndoAction</a>()</pre>
 </li>
 </ul>
 <a name="testTableSkewCost--">
@@ -463,7 +463,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testTableSkewCost</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.355">testTableSkewCost</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.357">testTableSkewCost</a>()</pre>
 </li>
 </ul>
 <a name="testRegionLoadCost--">
@@ -472,7 +472,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testRegionLoadCost</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.369">testRegionLoadCost</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.371">testRegionLoadCost</a>()</pre>
 </li>
 </ul>
 <a name="testCostFromArray--">
@@ -481,7 +481,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockList">
 <li class="blockList">
 <h4>testCostFromArray</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.400">testCostFromArray</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.402">testCostFromArray</a>()</pre>
 </li>
 </ul>
 <a name="testLosingRs--">
@@ -490,7 +490,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/Balan
 <ul class="blockListLast">
 <li class="blockList">
 <h4>testLosingRs</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.428">testLosingRs</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/TestStochasticLoadBalancer.html#line.430">testLosingRs</a>()
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
index 8a2eacd..e3d7919 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -580,14 +580,14 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ResourceChecker.Phase.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ResourceChecker.Phase</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleCommand.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleCommand</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ScanPerformanceEvaluation.ScanCounter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ScanPerformanceEvaluation.ScanCounter</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.CommandProvider.Operation.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.CommandProvider.Operation</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ScanPerformanceEvaluation.ScanCounter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ScanPerformanceEvaluation.ScanCounter</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
index a1c9b1d..28973e0 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure/package-tree.html
@@ -81,14 +81,14 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Object</span></a>
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
+<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
 </ul>
 </li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.Procedure&lt;TEnvironment&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;)
+<li type="circle">org.apache.hadoop.hbase.procedure.Procedure (implements java.util.concurrent.<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;V&gt;, org.apache.hadoop.hbase.errorhandling.ForeignExceptionListener)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedureDescriber.TestProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedureDescriber.TestProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure.<a href="../../../../../org/apache/hadoop/hbase/procedure/TestProcedure.LatchedProcedure.html" title="class in org.apache.hadoop.hbase.procedure"><span class="typeNameLink">TestProcedure.LatchedProcedure</span></a></li>
 </ul>
 </li>
 <li type="circle">org.apache.hadoop.hbase.procedure.ProcedureManager

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index e4a95a9..300aafe 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -234,9 +234,9 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.TestSMProcedureState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestStateMachineProcedure.TestSMProcedureState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestYieldProcedures.TestStateMachineProcedure.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureBypass.StuckStateMachineState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureBypass.StuckStateMachineState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
 </ul>
 </li>
 </ul>


[10/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
index 083ab07..be28dfa 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html
@@ -31,54 +31,54 @@
 <span class="sourceLineNo">023</span>import java.util.Collection;<a name="line.23"></a>
 <span class="sourceLineNo">024</span>import java.util.Collections;<a name="line.24"></a>
 <span class="sourceLineNo">025</span>import java.util.HashMap;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.HashSet;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.Iterator;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import java.util.List;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import java.util.Map;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import java.util.NavigableSet;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import java.util.Set;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import java.util.SortedSet;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import java.util.TreeSet;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import java.util.UUID;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import java.util.concurrent.ConcurrentMap;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import java.util.concurrent.Future;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import java.util.concurrent.RejectedExecutionException;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import java.util.concurrent.TimeUnit;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import java.util.stream.Collectors;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.conf.Configuration;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.FileSystem;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.fs.Path;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.HConstants;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.Server;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.ServerName;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.TableName;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.63"></a>
-<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.67"></a>
-<span class="sourceLineNo">068</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.68"></a>
-<span class="sourceLineNo">069</span>import org.apache.zookeeper.KeeperException;<a name="line.69"></a>
-<span class="sourceLineNo">070</span>import org.slf4j.Logger;<a name="line.70"></a>
-<span class="sourceLineNo">071</span>import org.slf4j.LoggerFactory;<a name="line.71"></a>
-<span class="sourceLineNo">072</span><a name="line.72"></a>
-<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.73"></a>
+<span class="sourceLineNo">026</span>import java.util.Iterator;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.NavigableSet;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import java.util.Set;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import java.util.SortedSet;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import java.util.TreeSet;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import java.util.UUID;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentMap;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import java.util.concurrent.Future;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import java.util.concurrent.RejectedExecutionException;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import java.util.concurrent.TimeUnit;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import java.util.stream.Collectors;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.conf.Configuration;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.fs.FileSystem;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.Path;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.HConstants;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.Server;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.ServerName;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.TableName;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.64"></a>
+<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.66"></a>
+<span class="sourceLineNo">067</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>import org.apache.zookeeper.KeeperException;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>import org.slf4j.Logger;<a name="line.69"></a>
+<span class="sourceLineNo">070</span>import org.slf4j.LoggerFactory;<a name="line.70"></a>
+<span class="sourceLineNo">071</span><a name="line.71"></a>
+<span class="sourceLineNo">072</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.collect.Sets;<a name="line.73"></a>
 <span class="sourceLineNo">074</span>import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;<a name="line.74"></a>
 <span class="sourceLineNo">075</span><a name="line.75"></a>
 <span class="sourceLineNo">076</span>/**<a name="line.76"></a>
@@ -156,7 +156,7 @@
 <span class="sourceLineNo">148</span>  private final Configuration conf;<a name="line.148"></a>
 <span class="sourceLineNo">149</span>  private final FileSystem fs;<a name="line.149"></a>
 <span class="sourceLineNo">150</span>  // The paths to the latest log of each wal group, for new coming peers<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private final Set&lt;Path&gt; latestPaths;<a name="line.151"></a>
+<span class="sourceLineNo">151</span>  private final Map&lt;String, Path&gt; latestPaths;<a name="line.151"></a>
 <span class="sourceLineNo">152</span>  // Path to the wals directories<a name="line.152"></a>
 <span class="sourceLineNo">153</span>  private final Path logDir;<a name="line.153"></a>
 <span class="sourceLineNo">154</span>  // Path to the wal archive<a name="line.154"></a>
@@ -224,7 +224,7 @@
 <span class="sourceLineNo">216</span>    tfb.setNameFormat("ReplicationExecutor-%d");<a name="line.216"></a>
 <span class="sourceLineNo">217</span>    tfb.setDaemon(true);<a name="line.217"></a>
 <span class="sourceLineNo">218</span>    this.executor.setThreadFactory(tfb.build());<a name="line.218"></a>
-<span class="sourceLineNo">219</span>    this.latestPaths = new HashSet&lt;Path&gt;();<a name="line.219"></a>
+<span class="sourceLineNo">219</span>    this.latestPaths = new HashMap&lt;&gt;();<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    this.replicationForBulkLoadDataEnabled = conf.getBoolean(<a name="line.220"></a>
 <span class="sourceLineNo">221</span>      HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, HConstants.REPLICATION_BULKLOAD_ENABLE_DEFAULT);<a name="line.221"></a>
 <span class="sourceLineNo">222</span>    this.sleepForRetries = this.conf.getLong("replication.source.sync.sleepforretries", 1000);<a name="line.222"></a>
@@ -379,756 +379,754 @@
 <span class="sourceLineNo">371</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByGroup = new HashMap&lt;&gt;();<a name="line.371"></a>
 <span class="sourceLineNo">372</span>      this.walsById.put(peerId, walsByGroup);<a name="line.372"></a>
 <span class="sourceLineNo">373</span>      // Add the latest wal to that source's queue<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      if (this.latestPaths.size() &gt; 0) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        for (Path logPath : latestPaths) {<a name="line.375"></a>
-<span class="sourceLineNo">376</span>          String name = logPath.getName();<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          String walPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(name);<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          NavigableSet&lt;String&gt; logs = new TreeSet&lt;&gt;();<a name="line.378"></a>
-<span class="sourceLineNo">379</span>          logs.add(name);<a name="line.379"></a>
-<span class="sourceLineNo">380</span>          walsByGroup.put(walPrefix, logs);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>          // Abort RS and throw exception to make add peer failed<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          abortAndThrowIOExceptionWhenFail(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, name));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          src.enqueueLog(logPath);<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>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    if (peerConfig.isSyncReplication()) {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    src.startup();<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    return src;<a name="line.393"></a>
-<span class="sourceLineNo">394</span>  }<a name="line.394"></a>
-<span class="sourceLineNo">395</span><a name="line.395"></a>
-<span class="sourceLineNo">396</span>  /**<a name="line.396"></a>
-<span class="sourceLineNo">397</span>   * &lt;p&gt;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.398"></a>
-<span class="sourceLineNo">399</span>   * &lt;/p&gt;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>   * &lt;p&gt;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.403"></a>
-<span class="sourceLineNo">404</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.404"></a>
-<span class="sourceLineNo">405</span>   * &lt;/p&gt;<a name="line.405"></a>
-<span class="sourceLineNo">406</span>   * &lt;p&gt;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>   * See HBASE-20426 for more details.<a name="line.407"></a>
-<span class="sourceLineNo">408</span>   * &lt;/p&gt;<a name="line.408"></a>
-<span class="sourceLineNo">409</span>   * @param peerId the id of the sync replication peer<a name="line.409"></a>
-<span class="sourceLineNo">410</span>   */<a name="line.410"></a>
-<span class="sourceLineNo">411</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    // walsById.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    ReplicationSourceInterface toRemove;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    synchronized (latestPaths) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      toRemove = sources.put(peerId, src);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      if (toRemove != null) {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        toRemove.terminate(terminateMessage);<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        toRemove.getSourceMetrics().clear();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      }<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.429"></a>
-<span class="sourceLineNo">430</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      // from the replication queue storage.<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    src.startup();<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      for (String wal : walsByGroup) {<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<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>    synchronized (walsById) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      wals.forEach((k, v) -&gt; {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        if (walsByGroup != null) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>          walsByGroup.removeAll(v);<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      });<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // simplify the logic.<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    synchronized (this.oldsources) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.455"></a>
-<span class="sourceLineNo">456</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.457"></a>
-<span class="sourceLineNo">458</span>          String queueId = oldSource.getQueueId();<a name="line.458"></a>
-<span class="sourceLineNo">459</span>          oldSource.terminate(terminateMessage);<a name="line.459"></a>
-<span class="sourceLineNo">460</span>          oldSource.getSourceMetrics().clear();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.461"></a>
-<span class="sourceLineNo">462</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.462"></a>
-<span class="sourceLineNo">463</span>          iter.remove();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        }<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /**<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.470"></a>
-<span class="sourceLineNo">471</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.471"></a>
-<span class="sourceLineNo">472</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.472"></a>
-<span class="sourceLineNo">473</span>   * @param peerId the id of the replication peer<a name="line.473"></a>
-<span class="sourceLineNo">474</span>   */<a name="line.474"></a>
-<span class="sourceLineNo">475</span>  public void refreshSources(String peerId) throws IOException {<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    String terminateMessage = "Peer " + peerId +<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    synchronized (this.latestPaths) {<a name="line.481"></a>
-<span class="sourceLineNo">482</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.482"></a>
-<span class="sourceLineNo">483</span>      if (toRemove != null) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        toRemove.terminate(terminateMessage);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      }<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      }<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    src.startup();<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.495"></a>
-<span class="sourceLineNo">496</span>    synchronized (this.oldsources) {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.500"></a>
-<span class="sourceLineNo">501</span>          oldSource.terminate(terminateMessage);<a name="line.501"></a>
-<span class="sourceLineNo">502</span>          this.oldsources.remove(oldSource);<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        }<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      }<a name="line.504"></a>
-<span class="sourceLineNo">505</span>      for (String queueId : previousQueueIds) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.506"></a>
-<span class="sourceLineNo">507</span>        this.oldsources.add(replicationSource);<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        toStartup.add(replicationSource);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>      }<a name="line.512"></a>
-<span class="sourceLineNo">513</span>    }<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      replicationSource.startup();<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
-<span class="sourceLineNo">517</span>  }<a name="line.517"></a>
-<span class="sourceLineNo">518</span><a name="line.518"></a>
-<span class="sourceLineNo">519</span>  /**<a name="line.519"></a>
-<span class="sourceLineNo">520</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.520"></a>
-<span class="sourceLineNo">521</span>   * @param src source to clear<a name="line.521"></a>
-<span class="sourceLineNo">522</span>   */<a name="line.522"></a>
-<span class="sourceLineNo">523</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    if (!this.oldsources.remove(src)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      return false;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    }<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    // Delete queue from storage and memory<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    deleteQueue(src.getQueueId());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    return true;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>  }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    synchronized (oldsources) {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      if (!removeRecoveredSource(src)) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.540"></a>
-<span class="sourceLineNo">541</span>      src.getStats());<a name="line.541"></a>
-<span class="sourceLineNo">542</span>  }<a name="line.542"></a>
-<span class="sourceLineNo">543</span><a name="line.543"></a>
-<span class="sourceLineNo">544</span>  /**<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.545"></a>
-<span class="sourceLineNo">546</span>   * @param src source to clear<a name="line.546"></a>
-<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
-<span class="sourceLineNo">548</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    this.sources.remove(src.getPeerId());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    // Delete queue from storage and memory<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    deleteQueue(src.getQueueId());<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    this.walsById.remove(src.getQueueId());<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  /**<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * Delete a complete queue of wals associated with a replication source<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @param queueId the id of replication queue to delete<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   */<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  private void deleteQueue(String queueId) {<a name="line.561"></a>
-<span class="sourceLineNo">562</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  }<a name="line.563"></a>
-<span class="sourceLineNo">564</span><a name="line.564"></a>
-<span class="sourceLineNo">565</span>  @FunctionalInterface<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  private interface ReplicationQueueOperation {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    void exec() throws ReplicationException;<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>  /**<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.571"></a>
-<span class="sourceLineNo">572</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
-<span class="sourceLineNo">574</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    try {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>      op.exec();<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    } catch (ReplicationException e) {<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.578"></a>
-<span class="sourceLineNo">579</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.579"></a>
-<span class="sourceLineNo">580</span>          .getCause() instanceof InterruptedException) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        throw new RuntimeException(<a name="line.581"></a>
-<span class="sourceLineNo">582</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      }<a name="line.583"></a>
-<span class="sourceLineNo">584</span>      server.abort("Failed to operate on replication queue", e);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    }<a name="line.585"></a>
-<span class="sourceLineNo">586</span>  }<a name="line.586"></a>
-<span class="sourceLineNo">587</span><a name="line.587"></a>
-<span class="sourceLineNo">588</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    try {<a name="line.589"></a>
-<span class="sourceLineNo">590</span>      op.exec();<a name="line.590"></a>
-<span class="sourceLineNo">591</span>    } catch (ReplicationException e) {<a name="line.591"></a>
-<span class="sourceLineNo">592</span>      server.abort("Failed to operate on replication queue", e);<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    }<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>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>    try {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      op.exec();<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    } catch (ReplicationException e) {<a name="line.599"></a>
-<span class="sourceLineNo">600</span>      throw new IOException(e);<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    }<a name="line.601"></a>
-<span class="sourceLineNo">602</span>  }<a name="line.602"></a>
-<span class="sourceLineNo">603</span><a name="line.603"></a>
-<span class="sourceLineNo">604</span>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    try {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      op.exec();<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    } catch (ReplicationException e) {<a name="line.607"></a>
-<span class="sourceLineNo">608</span>      server.abort("Failed to operate on replication queue", e);<a name="line.608"></a>
-<span class="sourceLineNo">609</span>      throw new IOException(e);<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><a name="line.612"></a>
-<span class="sourceLineNo">613</span>  /**<a name="line.613"></a>
-<span class="sourceLineNo">614</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.614"></a>
-<span class="sourceLineNo">615</span>   * replication queue.<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * @param source the replication source<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.617"></a>
-<span class="sourceLineNo">618</span>   */<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.619"></a>
-<span class="sourceLineNo">620</span>      WALEntryBatch entryBatch) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.622"></a>
-<span class="sourceLineNo">623</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.623"></a>
-<span class="sourceLineNo">624</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<a name="line.624"></a>
-<span class="sourceLineNo">625</span>  }<a name="line.625"></a>
-<span class="sourceLineNo">626</span><a name="line.626"></a>
-<span class="sourceLineNo">627</span>  /**<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * file is closed and has no more entries.<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   * @param log Path to the log<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   * @param inclusive whether we should also remove the given log file<a name="line.631"></a>
-<span class="sourceLineNo">632</span>   * @param source the replication source<a name="line.632"></a>
-<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
-<span class="sourceLineNo">634</span>  @VisibleForTesting<a name="line.634"></a>
-<span class="sourceLineNo">635</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    if (source.isRecovered()) {<a name="line.637"></a>
-<span class="sourceLineNo">638</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (wals != null) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.640"></a>
-<span class="sourceLineNo">641</span>        if (walsToRemove.isEmpty()) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>          return;<a name="line.642"></a>
-<span class="sourceLineNo">643</span>        }<a name="line.643"></a>
-<span class="sourceLineNo">644</span>        cleanOldLogs(walsToRemove, source);<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        walsToRemove.clear();<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      }<a name="line.646"></a>
-<span class="sourceLineNo">647</span>    } else {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; wals;<a name="line.648"></a>
-<span class="sourceLineNo">649</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.649"></a>
-<span class="sourceLineNo">650</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      synchronized (this.walsById) {<a name="line.651"></a>
-<span class="sourceLineNo">652</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.652"></a>
-<span class="sourceLineNo">653</span>        if (wals == null) {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>          return;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>        }<a name="line.655"></a>
-<span class="sourceLineNo">656</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>        if (walsToRemove.isEmpty()) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>          return;<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        }<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.660"></a>
-<span class="sourceLineNo">661</span>      }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      // the lock to avoid block preLogRoll<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      cleanOldLogs(walsToRemove, source);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      // now let's remove the files in the set<a name="line.666"></a>
-<span class="sourceLineNo">667</span>      synchronized (this.walsById) {<a name="line.667"></a>
-<span class="sourceLineNo">668</span>        wals.removeAll(walsToRemove);<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      }<a name="line.669"></a>
-<span class="sourceLineNo">670</span>    }<a name="line.670"></a>
-<span class="sourceLineNo">671</span>  }<a name="line.671"></a>
-<span class="sourceLineNo">672</span><a name="line.672"></a>
-<span class="sourceLineNo">673</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      throws IOException {<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    for (String wal : wals) {<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      try {<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.680"></a>
-<span class="sourceLineNo">681</span>          throw new IOException("Can not delete " + walFile);<a name="line.681"></a>
-<span class="sourceLineNo">682</span>        }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>      } catch (FileNotFoundException e) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>        // Just ignore since this means the file has already been deleted.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.686"></a>
-<span class="sourceLineNo">687</span>        // FileSystem.delete, and also catch FNFE.<a name="line.687"></a>
-<span class="sourceLineNo">688</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<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>  }<a name="line.691"></a>
-<span class="sourceLineNo">692</span><a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void cleanOldLogs(NavigableSet&lt;String&gt; wals, ReplicationSourceInterface source) {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    LOG.debug("Removing {} logs in the list: {}", wals.size(), wals);<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    // The intention here is that, we want to delete the remote wal files ASAP as it may effect the<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // failover time if you want to transit the remote cluster from S to A. And the infinite retry<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    // is not a problem, as if we can not contact with the remote HDFS cluster, then usually we can<a name="line.697"></a>
-<span class="sourceLineNo">698</span>    // not contact with the HBase cluster either, so the replication will be blocked either.<a name="line.698"></a>
-<span class="sourceLineNo">699</span>    if (source.isSyncReplication()) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      String peerId = source.getPeerId();<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      String remoteWALDir = source.getPeer().getPeerConfig().getRemoteWALDir();<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      // Filter out the wals need to be removed from the remote directory. Its name should be the<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      // special format, and also, the peer id in its name should match the peer id for the<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      // replication source.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      List&lt;String&gt; remoteWals = wals.stream().filter(w -&gt; SyncReplicationWALProvider<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        .getSyncReplicationPeerIdFromWALName(w).map(peerId::equals).orElse(false))<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        .collect(Collectors.toList());<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.debug("Removing {} logs from remote dir {} in the list: {}", remoteWals.size(),<a name="line.708"></a>
-<span class="sourceLineNo">709</span>        remoteWALDir, remoteWals);<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      if (!remoteWals.isEmpty()) {<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        for (int sleepMultiplier = 0;;) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>          try {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>            removeRemoteWALs(peerId, remoteWALDir, remoteWals);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>            break;<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          } catch (IOException e) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>            LOG.warn("Failed to delete remote wals from remote dir {} for peer {}", remoteWALDir,<a name="line.716"></a>
-<span class="sourceLineNo">717</span>              peerId);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          }<a name="line.718"></a>
-<span class="sourceLineNo">719</span>          if (!source.isSourceActive()) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>            // skip the following operations<a name="line.720"></a>
-<span class="sourceLineNo">721</span>            return;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>          }<a name="line.722"></a>
-<span class="sourceLineNo">723</span>          if (ReplicationUtils.sleepForRetries("Failed to delete remote wals", sleepForRetries,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>            sleepMultiplier, maxRetriesMultiplier)) {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>            sleepMultiplier++;<a name="line.725"></a>
-<span class="sourceLineNo">726</span>          }<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        }<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>    String queueId = source.getQueueId();<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    for (String wal : wals) {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      interruptOrAbortWhenFail(<a name="line.732"></a>
-<span class="sourceLineNo">733</span>        () -&gt; this.queueStorage.removeWAL(server.getServerName(), queueId, wal));<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    }<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  // public because of we call it in TestReplicationEmptyWALRecovery<a name="line.737"></a>
-<span class="sourceLineNo">738</span>  @VisibleForTesting<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  public void preLogRoll(Path newLog) throws IOException {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>    String logName = newLog.getName();<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(logName);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // synchronized on latestPaths to avoid the new open source miss the new log<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    synchronized (this.latestPaths) {<a name="line.743"></a>
-<span class="sourceLineNo">744</span>      // Add log to queue storage<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      for (ReplicationSourceInterface source : this.sources.values()) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>        // If record log to queue storage failed, abort RS and throw exception to make log roll<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        // failed<a name="line.747"></a>
-<span class="sourceLineNo">748</span>        abortAndThrowIOExceptionWhenFail(<a name="line.748"></a>
-<span class="sourceLineNo">749</span>          () -&gt; this.queueStorage.addWAL(server.getServerName(), source.getQueueId(), logName));<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
-<span class="sourceLineNo">751</span><a name="line.751"></a>
-<span class="sourceLineNo">752</span>      // synchronized on walsById to avoid race with cleanOldLogs<a name="line.752"></a>
-<span class="sourceLineNo">753</span>      synchronized (this.walsById) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>        // Update walsById map<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        for (Map.Entry&lt;String, Map&lt;String, NavigableSet&lt;String&gt;&gt;&gt; entry : this.walsById<a name="line.755"></a>
-<span class="sourceLineNo">756</span>          .entrySet()) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>          String peerId = entry.getKey();<a name="line.757"></a>
-<span class="sourceLineNo">758</span>          Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByPrefix = entry.getValue();<a name="line.758"></a>
-<span class="sourceLineNo">759</span>          boolean existingPrefix = false;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>          for (Map.Entry&lt;String, NavigableSet&lt;String&gt;&gt; walsEntry : walsByPrefix.entrySet()) {<a name="line.760"></a>
-<span class="sourceLineNo">761</span>            SortedSet&lt;String&gt; wals = walsEntry.getValue();<a name="line.761"></a>
-<span class="sourceLineNo">762</span>            if (this.sources.isEmpty()) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>              // If there's no slaves, don't need to keep the old wals since<a name="line.763"></a>
-<span class="sourceLineNo">764</span>              // we only consider the last one when a new slave comes in<a name="line.764"></a>
-<span class="sourceLineNo">765</span>              wals.clear();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>            }<a name="line.766"></a>
-<span class="sourceLineNo">767</span>            if (logPrefix.equals(walsEntry.getKey())) {<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              wals.add(logName);<a name="line.768"></a>
-<span class="sourceLineNo">769</span>              existingPrefix = true;<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            }<a name="line.770"></a>
-<span class="sourceLineNo">771</span>          }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>          if (!existingPrefix) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>            // The new log belongs to a new group, add it into this peer<a name="line.773"></a>
-<span class="sourceLineNo">774</span>            LOG.debug("Start tracking logs for wal group {} for peer {}", logPrefix, peerId);<a name="line.774"></a>
-<span class="sourceLineNo">775</span>            NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.775"></a>
-<span class="sourceLineNo">776</span>            wals.add(logName);<a name="line.776"></a>
-<span class="sourceLineNo">777</span>            walsByPrefix.put(logPrefix, wals);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>          }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>        }<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      }<a name="line.780"></a>
-<span class="sourceLineNo">781</span><a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Add to latestPaths<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      Iterator&lt;Path&gt; iterator = latestPaths.iterator();<a name="line.783"></a>
-<span class="sourceLineNo">784</span>      while (iterator.hasNext()) {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        Path path = iterator.next();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>        if (path.getName().contains(logPrefix)) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>          iterator.remove();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>          break;<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        }<a name="line.789"></a>
-<span class="sourceLineNo">790</span>      }<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      this.latestPaths.add(newLog);<a name="line.791"></a>
+<span class="sourceLineNo">374</span>      if (!latestPaths.isEmpty()) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        for (Map.Entry&lt;String, Path&gt; walPrefixAndPath : latestPaths.entrySet()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          Path walPath = walPrefixAndPath.getValue();<a name="line.376"></a>
+<span class="sourceLineNo">377</span>          NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.377"></a>
+<span class="sourceLineNo">378</span>          wals.add(walPath.getName());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          walsByGroup.put(walPrefixAndPath.getKey(), wals);<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          // Abort RS and throw exception to make add peer failed<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          abortAndThrowIOExceptionWhenFail(<a name="line.381"></a>
+<span class="sourceLineNo">382</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, walPath.getName()));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          src.enqueueLog(walPath);<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        }<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>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.387"></a>
+<span class="sourceLineNo">388</span>    if (peerConfig.isSyncReplication()) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    src.startup();<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    return src;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  }<a name="line.393"></a>
+<span class="sourceLineNo">394</span><a name="line.394"></a>
+<span class="sourceLineNo">395</span>  /**<a name="line.395"></a>
+<span class="sourceLineNo">396</span>   * &lt;p&gt;<a name="line.396"></a>
+<span class="sourceLineNo">397</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>   * &lt;/p&gt;<a name="line.398"></a>
+<span class="sourceLineNo">399</span>   * &lt;p&gt;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.400"></a>
+<span class="sourceLineNo">401</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * &lt;/p&gt;<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   * &lt;p&gt;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * See HBASE-20426 for more details.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   * &lt;/p&gt;<a name="line.407"></a>
+<span class="sourceLineNo">408</span>   * @param peerId the id of the sync replication peer<a name="line.408"></a>
+<span class="sourceLineNo">409</span>   */<a name="line.409"></a>
+<span class="sourceLineNo">410</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    // walsById.<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    ReplicationSourceInterface toRemove;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    synchronized (latestPaths) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      toRemove = sources.put(peerId, src);<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      if (toRemove != null) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        toRemove.terminate(terminateMessage);<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        toRemove.getSourceMetrics().clear();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      }<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.429"></a>
+<span class="sourceLineNo">430</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      // from the replication queue storage.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    src.startup();<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.436"></a>
+<span class="sourceLineNo">437</span>      for (String wal : walsByGroup) {<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    synchronized (walsById) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>      wals.forEach((k, v) -&gt; {<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>        if (walsByGroup != null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>          walsByGroup.removeAll(v);<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      });<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // simplify the logic.<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    synchronized (this.oldsources) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.454"></a>
+<span class="sourceLineNo">455</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.455"></a>
+<span class="sourceLineNo">456</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>          String queueId = oldSource.getQueueId();<a name="line.457"></a>
+<span class="sourceLineNo">458</span>          oldSource.terminate(terminateMessage);<a name="line.458"></a>
+<span class="sourceLineNo">459</span>          oldSource.getSourceMetrics().clear();<a name="line.459"></a>
+<span class="sourceLineNo">460</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.460"></a>
+<span class="sourceLineNo">461</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.461"></a>
+<span class="sourceLineNo">462</span>          iter.remove();<a name="line.462"></a>
+<span class="sourceLineNo">463</span>        }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.471"></a>
+<span class="sourceLineNo">472</span>   * @param peerId the id of the replication peer<a name="line.472"></a>
+<span class="sourceLineNo">473</span>   */<a name="line.473"></a>
+<span class="sourceLineNo">474</span>  public void refreshSources(String peerId) throws IOException {<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    String terminateMessage = "Peer " + peerId +<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.478"></a>
+<span class="sourceLineNo">479</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    synchronized (this.latestPaths) {<a name="line.480"></a>
+<span class="sourceLineNo">481</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.481"></a>
+<span class="sourceLineNo">482</span>      if (toRemove != null) {<a name="line.482"></a>
+<span class="sourceLineNo">483</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.483"></a>
+<span class="sourceLineNo">484</span>        toRemove.terminate(terminateMessage);<a name="line.484"></a>
+<span class="sourceLineNo">485</span>      }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.487"></a>
+<span class="sourceLineNo">488</span>      }<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    }<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    src.startup();<a name="line.491"></a>
+<span class="sourceLineNo">492</span><a name="line.492"></a>
+<span class="sourceLineNo">493</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.493"></a>
+<span class="sourceLineNo">494</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.494"></a>
+<span class="sourceLineNo">495</span>    synchronized (this.oldsources) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.496"></a>
+<span class="sourceLineNo">497</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.499"></a>
+<span class="sourceLineNo">500</span>          oldSource.terminate(terminateMessage);<a name="line.500"></a>
+<span class="sourceLineNo">501</span>          this.oldsources.remove(oldSource);<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>      for (String queueId : previousQueueIds) {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.505"></a>
+<span class="sourceLineNo">506</span>        this.oldsources.add(replicationSource);<a name="line.506"></a>
+<span class="sourceLineNo">507</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.507"></a>
+<span class="sourceLineNo">508</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
+<span class="sourceLineNo">510</span>        toStartup.add(replicationSource);<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      }<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      replicationSource.startup();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
+<span class="sourceLineNo">516</span>  }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>  /**<a name="line.518"></a>
+<span class="sourceLineNo">519</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.519"></a>
+<span class="sourceLineNo">520</span>   * @param src source to clear<a name="line.520"></a>
+<span class="sourceLineNo">521</span>   */<a name="line.521"></a>
+<span class="sourceLineNo">522</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    if (!this.oldsources.remove(src)) {<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      return false;<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    // Delete queue from storage and memory<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    deleteQueue(src.getQueueId());<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    return true;<a name="line.530"></a>
+<span class="sourceLineNo">531</span>  }<a name="line.531"></a>
+<span class="sourceLineNo">532</span><a name="line.532"></a>
+<span class="sourceLineNo">533</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.533"></a>
+<span class="sourceLineNo">534</span>    synchronized (oldsources) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      if (!removeRecoveredSource(src)) {<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      src.getStats());<a name="line.540"></a>
+<span class="sourceLineNo">541</span>  }<a name="line.541"></a>
+<span class="sourceLineNo">542</span><a name="line.542"></a>
+<span class="sourceLineNo">543</span>  /**<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param src source to clear<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   */<a name="line.546"></a>
+<span class="sourceLineNo">547</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    this.sources.remove(src.getPeerId());<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    // Delete queue from storage and memory<a name="line.550"></a>
+<span class="sourceLineNo">551</span>    deleteQueue(src.getQueueId());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    this.walsById.remove(src.getQueueId());<a name="line.552"></a>
+<span class="sourceLineNo">553</span><a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
+<span class="sourceLineNo">557</span>   * Delete a complete queue of wals associated with a replication source<a name="line.557"></a>
+<span class="sourceLineNo">558</span>   * @param queueId the id of replication queue to delete<a name="line.558"></a>
+<span class="sourceLineNo">559</span>   */<a name="line.559"></a>
+<span class="sourceLineNo">560</span>  private void deleteQueue(String queueId) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.561"></a>
+<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
+<span class="sourceLineNo">563</span><a name="line.563"></a>
+<span class="sourceLineNo">564</span>  @FunctionalInterface<a name="line.564"></a>
+<span class="sourceLineNo">565</span>  private interface ReplicationQueueOperation {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    void exec() throws ReplicationException;<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>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.570"></a>
+<span class="sourceLineNo">571</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   */<a name="line.572"></a>
+<span class="sourceLineNo">573</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.573"></a>
+<span class="sourceLineNo">574</span>    try {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>      op.exec();<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    } catch (ReplicationException e) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.577"></a>
+<span class="sourceLineNo">578</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.578"></a>
+<span class="sourceLineNo">579</span>          .getCause() instanceof InterruptedException) {<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        throw new RuntimeException(<a name="line.580"></a>
+<span class="sourceLineNo">581</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.581"></a>
+<span class="sourceLineNo">582</span>      }<a name="line.582"></a>
+<span class="sourceLineNo">583</span>      server.abort("Failed to operate on replication queue", e);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    }<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.587"></a>
+<span class="sourceLineNo">588</span>    try {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>      op.exec();<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    } catch (ReplicationException e) {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>      server.abort("Failed to operate on replication queue", e);<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><a name="line.594"></a>
+<span class="sourceLineNo">595</span>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    try {<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      op.exec();<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    } catch (ReplicationException e) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      throw new IOException(e);<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>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    try {<a name="line.604"></a>
+<span class="sourceLineNo">605</span>      op.exec();<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    } catch (ReplicationException e) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      server.abort("Failed to operate on replication queue", e);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      throw new IOException(e);<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>  /**<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.613"></a>
+<span class="sourceLineNo">614</span>   * replication queue.<a name="line.614"></a>
+<span class="sourceLineNo">615</span>   * @param source the replication source<a name="line.615"></a>
+<span class="sourceLineNo">616</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.616"></a>
+<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
+<span class="sourceLineNo">618</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      WALEntryBatch entryBatch) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<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>  /**<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   * file is closed and has no more entries.<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param log Path to the log<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param inclusive whether we should also remove the given log file<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @param source the replication source<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   */<a name="line.632"></a>
+<span class="sourceLineNo">633</span>  @VisibleForTesting<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.635"></a>
+<span class="sourceLineNo">636</span>    if (source.isRecovered()) {<a name="line.636"></a>
+<span class="sourceLineNo">637</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (wals != null) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.639"></a>
+<span class="sourceLineNo">640</span>        if (walsToRemove.isEmpty()) {<a name="line.640"></a>
+<span class="sourceLineNo">641</span>          return;<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        }<a name="line.642"></a>
+<span class="sourceLineNo">643</span>        cleanOldLogs(walsToRemove, source);<a name="line.643"></a>
+<span class="sourceLineNo">644</span>        walsToRemove.clear();<a name="line.644"></a>
+<span class="sourceLineNo">645</span>      }<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    } else {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      NavigableSet&lt;String&gt; wals;<a name="line.647"></a>
+<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      synchronized (this.walsById) {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        if (wals == null) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>          return;<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        }<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (walsToRemove.isEmpty()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return;<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      }<a name="line.660"></a>
+<span class="sourceLineNo">661</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.662"></a>
+<span class="sourceLineNo">663</span>      // the lock to avoid block preLogRoll<a name="line.663"></a>
+<span class="sourceLineNo">664</span>      cleanOldLogs(walsToRemove, source);<a name="line.664"></a>
+<span class="sourceLineNo">665</span>      // now let's remove the files in the set<a name="line.665"></a>
+<span class="sourceLineNo">666</span>      synchronized (this.walsById) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>        wals.removeAll(walsToRemove);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>      }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    }<a name="line.669"></a>
+<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
+<span class="sourceLineNo">671</span><a name="line.671"></a>
+<span class="sourceLineNo">672</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.672"></a>
+<span class="sourceLineNo">673</span>      throws IOException {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    for (String wal : wals) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      try {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          throw new IOException("Can not delete " + walFile);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>        }<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      } catch (FileNotFoundException e) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>        // Just ignore since this means the file has already been deleted.<a name="line.683"></a>
+<span class="sourceLineNo">684</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.684"></a>
+<span class="sourceLineNo">685</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.685"></a>
+<span class="sourceLineNo">686</span>        // FileSystem.delete, and also catch FNFE.<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<a name="line.687"></a>
+<span class="sourceLineNo">688</span>      }<a name="line.688"

<TRUNCATED>

[43/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/book.html
----------------------------------------------------------------------
diff --git a/book.html b/book.html
index 4523e86..9aec55c 100644
--- a/book.html
+++ b/book.html
@@ -29312,6 +29312,52 @@ Following are a few examples of the reporting capabilities.</p>
 Have a look in the Web UI.</p>
 </div>
 </div>
+<div class="sect2">
+<h3 id="_snapshot_space_usage_monitoring"><a class="anchor" href="#_snapshot_space_usage_monitoring"></a>153.4. Snapshot Space Usage Monitoring</h3>
+<div class="paragraph">
+<p>Starting with HBase 0.95, Snapshot usage information on individual snapshots was shown in the HBase Master Web UI. This was further enhanced starting with HBase 1.3 to show the total Storefile size of the Snapshot Set. The following metrics are shown in the Master Web UI with HBase 1.3 and later.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Shared Storefile Size is the Storefile size shared between snapshots and active tables.</p>
+</li>
+<li>
+<p>Mob Storefile Size is the Mob Storefile size shared between snapshots and active tables.</p>
+</li>
+<li>
+<p>Archived Storefile Size is the Storefile size in Archive.</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>The format of Archived Storefile Size is NNN(MMM). NNN is the total Storefile size in Archive, MMM is the total Storefile size in Archive that is specific to the snapshot (not shared with other snapshots and tables).</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<img src="images/master-snapshot.png" alt="master snapshot">
+</div>
+<div class="title">Figure 12. Master Snapshot Overview</div>
+</div>
+<div class="imageblock">
+<div class="content">
+<img src="images/1-snapshot.png" alt="1 snapshot">
+</div>
+<div class="title">Figure 13. Snapshot Storefile Stats Example 1</div>
+</div>
+<div class="imageblock">
+<div class="content">
+<img src="images/2-snapshots.png" alt="2 snapshots">
+</div>
+<div class="title">Figure 14. Snapshot Storefile Stats Example 2</div>
+</div>
+<div class="imageblock">
+<div class="content">
+<img src="images/empty-snapshots.png" alt="empty snapshots">
+</div>
+<div class="title">Figure 15. Empty Snapshot Storfile Stats Example</div>
+</div>
+</div>
 </div>
 </div>
 <div class="sect1">
@@ -29461,7 +29507,7 @@ Use the arrows to follow the data paths.</p>
 <div class="content">
 <img src="images/hbase_replication_diagram.jpg" alt="hbase replication diagram">
 </div>
-<div class="title">Figure 12. Example of a Complex Cluster Replication Configuration</div>
+<div class="title">Figure 16. Example of a Complex Cluster Replication Configuration</div>
 </div>
 <div class="paragraph">
 <p>HBase replication borrows many concepts from the <em class="firstterm">statement-based replication</em> design used by MySQL.
@@ -29618,7 +29664,7 @@ The <code>VerifyReplication</code> command prints out <code>GOODROWS</code> and
 <div class="content">
 <img src="images/replication_overview.png" alt="replication overview">
 </div>
-<div class="title">Figure 13. Replication Architecture Overview</div>
+<div class="title">Figure 17. Replication Architecture Overview</div>
 </div>
 <div class="sect3">
 <h4 id="_life_of_a_wal_edit"><a class="anchor" href="#_life_of_a_wal_edit"></a>154.5.1. Life of a WAL Edit</h4>
@@ -37779,7 +37825,7 @@ Assuming the first key here is totally different from the key before, its prefix
 <div class="content">
 <img src="images/data_block_no_encoding.png" alt="data block no encoding">
 </div>
-<div class="title">Figure 14. ColumnFamily with No Encoding</div>
+<div class="title">Figure 18. ColumnFamily with No Encoding</div>
 </div>
 <div class="paragraph">
 <p>Here is the same data with prefix data encoding.</p>
@@ -37788,7 +37834,7 @@ Assuming the first key here is totally different from the key before, its prefix
 <div class="content">
 <img src="images/data_block_prefix_encoding.png" alt="data block prefix encoding">
 </div>
-<div class="title">Figure 15. ColumnFamily with Prefix Encoding</div>
+<div class="title">Figure 19. ColumnFamily with Prefix Encoding</div>
 </div>
 </dd>
 <dt class="hdlist1">Diff</dt>
@@ -37818,7 +37864,7 @@ Given the two row keys in the Prefix example, and given an exact match on timest
 <div class="content">
 <img src="images/data_block_diff_encoding.png" alt="data block diff encoding">
 </div>
-<div class="title">Figure 16. ColumnFamily with Diff Encoding</div>
+<div class="title">Figure 20. ColumnFamily with Diff Encoding</div>
 </div>
 </dd>
 <dt class="hdlist1">Fast Diff</dt>
@@ -38319,7 +38365,7 @@ See <a href="https://github.com/tdunning/YCSB">Ted Dunning&#8217;s YCSB</a>.</p>
 <div class="content">
 <img src="images/hfile.png" alt="HFile Version 1">
 </div>
-<div class="title">Figure 17. HFile V1 Format</div>
+<div class="title">Figure 21. HFile V1 Format</div>
 </div>
 </div>
 <div class="sect3">
@@ -38400,7 +38446,7 @@ A version 2 HFile is structured as follows:</p>
 <div class="content">
 <img src="images/hfilev2.png" alt="HFile Version 2">
 </div>
-<div class="title">Figure 18. HFile Version 2 Structure</div>
+<div class="title">Figure 22. HFile Version 2 Structure</div>
 </div>
 </div>
 <div class="sect3">
@@ -39043,7 +39089,7 @@ See <a href="https://www.apache.org/foundation/board/reporting">ASF board report
 <div class="content">
 <img src="images/jumping-orca_rotated_25percent.png" alt="jumping orca rotated 25percent">
 </div>
-<div class="title">Figure 19. Apache HBase Orca, HBase Colors, &amp; Font</div>
+<div class="title">Figure 23. Apache HBase Orca, HBase Colors, &amp; Font</div>
 </div>
 <div class="paragraph">
 <p><a href="https://issues.apache.org/jira/browse/HBASE-4920">An Orca is the Apache HBase mascot.</a> See NOTICES.txt.
@@ -41272,7 +41318,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 2018-11-08 14:33:09 UTC
+Last updated 2018-11-09 14:33:44 UTC
 </div>
 </div>
 </body>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/bulk-loads.html
----------------------------------------------------------------------
diff --git a/bulk-loads.html b/bulk-loads.html
index 5006398..65a62c8 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Bulk Loads in Apache HBase (TM)
@@ -316,7 +316,7 @@ under the License. -->
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/checkstyle-aggregate.html
----------------------------------------------------------------------
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 070c1a3..a98b531 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Checkstyle Results</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -294,7 +294,7 @@
 <td>3804</td>
 <td>0</td>
 <td>0</td>
-<td>15099</td></tr></table></div>
+<td>15097</td></tr></table></div>
 <div class="section">
 <h2><a name="Files"></a>Files</h2>
 <table border="0" class="table table-striped">
@@ -7467,7 +7467,7 @@
 <td><a href="#org.apache.hadoop.hbase.regionserver.wal.ProtobufLogReader.java">org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.java</a></td>
 <td>0</td>
 <td>0</td>
-<td>22</td></tr>
+<td>20</td></tr>
 <tr class="a">
 <td><a href="#org.apache.hadoop.hbase.regionserver.wal.ReaderBase.java">org/apache/hadoop/hbase/regionserver/wal/ReaderBase.java</a></td>
 <td>0</td>
@@ -9849,7 +9849,7 @@
 <ul>
 <li>max: <tt>&quot;100&quot;</tt></li>
 <li>ignorePattern: <tt>&quot;^package.*|^import.*|a href|href|http://|https://|ftp://|org.apache.thrift.|com.google.protobuf.|hbase.protobuf.generated&quot;</tt></li></ul></td>
-<td>1445</td>
+<td>1443</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td></td>
@@ -26387,343 +26387,343 @@
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' child has incorrect indentation level 12, expected level should be 10.</td>
-<td>122</td></tr>
+<td>124</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' child has incorrect indentation level 12, expected level should be 10.</td>
-<td>126</td></tr>
+<td>128</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>140</td></tr>
+<td>142</td></tr>
 <tr class="b">
 <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>142</td></tr>
+<td>144</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>144</td></tr>
+<td>146</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 rcurly' has incorrect indentation level 2, expected level should be 4.</td>
-<td>147</td></tr>
+<td>149</td></tr>
 <tr class="a">
 <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>152</td></tr>
+<td>154</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>223</td></tr>
+<td>225</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>224</td></tr>
+<td>226</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>226</td></tr>
+<td>228</td></tr>
 <tr class="a">
 <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>227</td></tr>
+<td>229</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>228</td></tr>
+<td>230</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>234</td></tr>
+<td>236</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>276</td></tr>
+<td>298</td></tr>
 <tr class="a">
 <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>284</td></tr>
+<td>306</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>318</td></tr>
+<td>340</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>320</td></tr>
+<td>342</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'.' has incorrect indentation level 6, expected level should be 8.</td>
-<td>333</td></tr>
+<td>355</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>341</td></tr>
+<td>363</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>343</td></tr>
+<td>365</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>347</td></tr>
+<td>369</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>352</td></tr>
+<td>374</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>353</td></tr>
+<td>375</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>354</td></tr>
+<td>376</td></tr>
 <tr class="a">
 <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>356</td></tr>
+<td>378</td></tr>
 <tr class="b">
 <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>360</td></tr>
+<td>382</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>371</td></tr>
+<td>393</td></tr>
 <tr class="b">
 <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>375</td></tr>
+<td>397</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>384</td></tr>
+<td>406</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'throws' has incorrect indentation level 2, expected level should be 4.</td>
-<td>388</td></tr>
+<td>410</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>406</td></tr>
+<td>428</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>407</td></tr>
+<td>429</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>428</td></tr>
+<td>450</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>452</td></tr>
+<td>474</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>466</td></tr>
+<td>488</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>480</td></tr>
+<td>502</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>483</td></tr>
+<td>505</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>496</td></tr>
+<td>518</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>510</td></tr>
+<td>532</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>513</td></tr>
+<td>535</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method call' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>565</td></tr>
+<td>587</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>591</td></tr>
+<td>613</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>593</td></tr>
+<td>615</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'throws' has incorrect indentation level 2, expected level should be 4.</td>
-<td>596</td></tr>
+<td>618</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' child has incorrect indentation level 4, expected level should be 6.</td>
-<td>620</td></tr>
+<td>642</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' child has incorrect indentation level 4, expected level should be 6.</td>
-<td>621</td></tr>
+<td>643</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method call' child has incorrect indentation level 8, expected level should be 10.</td>
-<td>632</td></tr>
+<td>654</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method call' child has incorrect indentation level 6, expected level should be 8.</td>
-<td>649</td></tr>
+<td>671</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method call' child has incorrect indentation level 4, expected level should be 6.</td>
-<td>653</td></tr>
+<td>675</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>672</td></tr>
+<td>694</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 112).</td>
-<td>692</td></tr>
+<td>714</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>694</td></tr>
+<td>716</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>696</td></tr>
+<td>718</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>706</td></tr>
+<td>728</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>708</td></tr>
+<td>730</td></tr>
 <tr class="b">
 <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>721</td></tr>
+<td>743</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>736</td></tr></table></div>
+<td>758</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.client.RegionInfoBuilder.java">org/apache/hadoop/hbase/client/RegionInfoBuilder.java</h3>
 <table border="0" class="table table-striped">
@@ -26756,19 +26756,19 @@
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method def' child has incorrect indentation level 7, expected level should be 6.</td>
-<td>369</td></tr>
+<td>361</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>413</td></tr>
+<td>405</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>445</td></tr></table></div>
+<td>437</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.client.RegionInfoDisplay.java">org/apache/hadoop/hbase/client/RegionInfoDisplay.java</h3>
 <table border="0" class="table table-striped">
@@ -65528,25 +65528,25 @@
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' child has incorrect indentation level 8, expected level should be 6.</td>
-<td>254</td></tr>
+<td>253</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>269</td></tr>
+<td>268</td></tr>
 <tr class="b">
 <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>271</td></tr>
+<td>270</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>461</td></tr>
+<td>460</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
@@ -66482,7 +66482,7 @@
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 107).</td>
-<td>475</td></tr></table></div>
+<td>477</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">
@@ -88814,22 +88814,10 @@
 <td>266</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 181).</td>
-<td>412</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 156).</td>
-<td>419</td></tr>
-<tr class="b">
-<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>441</td></tr></table></div>
+<td>457</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.regionserver.wal.ReaderBase.java">org/apache/hadoop/hbase/regionserver/wal/ReaderBase.java</h3>
 <table border="0" class="table table-striped">
@@ -90362,13 +90350,13 @@
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>690</td></tr>
+<td>706</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>691</td></tr></table></div>
+<td>707</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.replication.regionserver.TestWALEntrySinkFilter.java">org/apache/hadoop/hbase/replication/regionserver/TestWALEntrySinkFilter.java</h3>
 <table border="0" class="table table-striped">
@@ -117399,7 +117387,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/checkstyle.rss
----------------------------------------------------------------------
diff --git a/checkstyle.rss b/checkstyle.rss
index 676ca49..c5a415e 100644
--- a/checkstyle.rss
+++ b/checkstyle.rss
@@ -26,7 +26,7 @@ under the License.
     <copyright>&#169;2007 - 2018 The Apache Software Foundation</copyright>
     <item>
       <title>File: 3804,
-             Errors: 15099,
+             Errors: 15097,
              Warnings: 0,
              Infos: 0
       </title>
@@ -47795,7 +47795,7 @@ under the License.
                   0
                 </td>
                 <td>
-                  22
+                  20
                 </td>
               </tr>
                           <tr>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/coc.html
----------------------------------------------------------------------
diff --git a/coc.html b/coc.html
index 0a5d73f..3212ffb 100644
--- a/coc.html
+++ b/coc.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Code of Conduct Policy
@@ -385,7 +385,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/dependencies.html
----------------------------------------------------------------------
diff --git a/dependencies.html b/dependencies.html
index e5c5f30..5f9d67f 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Dependencies</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -450,7 +450,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/dependency-convergence.html
----------------------------------------------------------------------
diff --git a/dependency-convergence.html b/dependency-convergence.html
index 2846e74..6c1f282 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Reactor Dependency Convergence</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -607,7 +607,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/dependency-info.html
----------------------------------------------------------------------
diff --git a/dependency-info.html b/dependency-info.html
index 803c158..f0af957 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Dependency Information</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -323,7 +323,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/dependency-management.html
----------------------------------------------------------------------
diff --git a/dependency-management.html b/dependency-management.html
index 9d97e54..132517c 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -7,7 +7,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="Date-Revision-yyyymmdd" content="20181108" />
+    <meta name="Date-Revision-yyyymmdd" content="20181109" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Dependency Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.4-HBase.min.css" />
@@ -1003,7 +1003,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-11-08</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-11-09</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/constant-values.html
----------------------------------------------------------------------
diff --git a/devapidocs/constant-values.html b/devapidocs/constant-values.html
index d33f3d6..8dd569d 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -3824,7 +3824,7 @@
 <!--   -->
 </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>"Thu Nov  8 14:43:17 UTC 2018"</code></td>
+<td class="colLast"><code>"Fri Nov  9 14:44:22 UTC 2018"</code></td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.revision">
@@ -3838,7 +3838,7 @@
 <!--   -->
 </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#srcChecksum">srcChecksum</a></code></td>
-<td class="colLast"><code>"ba26694ecff3f263f83aeb7b880a430c"</code></td>
+<td class="colLast"><code>"2006cc481839aabfb5ea846c19b440b9"</code></td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.url">

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/index-all.html
----------------------------------------------------------------------
diff --git a/devapidocs/index-all.html b/devapidocs/index-all.html
index fc0526e..9b76024 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -41603,6 +41603,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.html#getLastDataBlockOffset--">getLastDataBlockOffset()</a></span> - Method in class org.apache.hadoop.hbase.io.hfile.<a href="org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.html" title="class in org.apache.hadoop.hbase.io.hfile">FixedFileTrailer</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getLastestPath--">getLastestPath()</a></span> - Method in class org.apache.hadoop.hbase.replication.regionserver.<a href="org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html" title="class in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/MasterRpcServices.html#getLastFlushedSequenceId-org.apache.hbase.thirdparty.com.google.protobuf.RpcController-org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest-">getLastFlushedSequenceId(RpcController, RegionServerStatusProtos.GetLastFlushedSequenceIdRequest)</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/MasterRpcServices.html" title="class in org.apache.hadoop.hbase.master">MasterRpcServices</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/ServerManager.html#getLastFlushedSequenceId-byte:A-">getLastFlushedSequenceId(byte[])</a></span> - Method in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/ServerManager.html" title="class in org.apache.hadoop.hbase.master">ServerManager</a></dt>
@@ -47642,6 +47644,10 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString--">getRegionNameAsString()</a></span> - Method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString(byte[])</a></span> - Static method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString(RegionInfo, byte[])</a></span> - Static method in interface org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html#getRegionNameAsString--">getRegionNameAsString()</a></span> - Method in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/RegionInfoBuilder.MutableRegionInfo.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder.MutableRegionInfo</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HRegionInfo.html#getRegionNameAsString--">getRegionNameAsString()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HRegionInfo.html" title="class in org.apache.hadoop.hbase">HRegionInfo</a></dt>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/HRegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/HRegionInfo.html b/devapidocs/org/apache/hadoop/hbase/HRegionInfo.html
index 3d7e107..ad61398 100644
--- a/devapidocs/org/apache/hadoop/hbase/HRegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/HRegionInfo.html
@@ -895,7 +895,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html"
 <!--   -->
 </a>
 <h3>Methods inherited from interface&nbsp;org.apache.hadoop.hbase.client.<a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></h3>
-<code><a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.Regi
 onInfo...-">toDelimitedByteArray</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
+<code><a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-
 byte:A-">hasEncodedName</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
index f55f5e6..0761683 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
@@ -167,10 +167,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/ImmutableHRegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/ImmutableHRegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/ImmutableHRegionInfo.html
index 0b36ac4..8b740b3 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/ImmutableHRegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/ImmutableHRegionInfo.html
@@ -217,7 +217,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/HRegionInfo.html" title=
 <!--   -->
 </a>
 <h3>Methods inherited from interface&nbsp;org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.had
 oop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo
 .html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
 </ul>
 </li>
 </ul>


[35/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html
----------------------------------------------------------------------
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 9d1542c..ec5f688 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
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        break;<a na

<TRUNCATED>

[28/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MemStoreSizeCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo"

<TRUNCATED>

[27/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.MoveCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        break;<a name="line.4

<TRUNCATED>

[12/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrContext.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrContext.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrContext.html
index 62e604e..0a58fc2 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrContext.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrContext.html
@@ -348,115 +348,131 @@
 <span class="sourceLineNo">340</span>      }<a name="line.340"></a>
 <span class="sourceLineNo">341</span>      WALKey.Builder builder = WALKey.newBuilder();<a name="line.341"></a>
 <span class="sourceLineNo">342</span>      long size = 0;<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      try {<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        long available = -1;<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        try {<a name="line.345"></a>
-<span class="sourceLineNo">346</span>          int firstByte = this.inputStream.read();<a name="line.346"></a>
-<span class="sourceLineNo">347</span>          if (firstByte == -1) {<a name="line.347"></a>
-<span class="sourceLineNo">348</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>          }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.350"></a>
-<span class="sourceLineNo">351</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          available = this.inputStream.available();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.354"></a>
-<span class="sourceLineNo">355</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.355"></a>
-<span class="sourceLineNo">356</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.356"></a>
-<span class="sourceLineNo">357</span>          }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.358"></a>
-<span class="sourceLineNo">359</span>            (int)size);<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.361"></a>
-<span class="sourceLineNo">362</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.362"></a>
-<span class="sourceLineNo">363</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        }<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        if (!builder.isInitialized()) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.367"></a>
-<span class="sourceLineNo">368</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.368"></a>
-<span class="sourceLineNo">369</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.369"></a>
-<span class="sourceLineNo">370</span>        }<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        WALKey walKey = builder.build();<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.373"></a>
-<span class="sourceLineNo">374</span>          if (LOG.isTraceEnabled()) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.375"></a>
-<span class="sourceLineNo">376</span>                this.inputStream.getPos());<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          continue;<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        long posBefore = this.inputStream.getPos();<a name="line.381"></a>
-<span class="sourceLineNo">382</span>        try {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          if (expectedCells != actualCells) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        } catch (Exception ex) {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.388"></a>
-<span class="sourceLineNo">389</span>          try {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.390"></a>
-<span class="sourceLineNo">391</span>          } catch (Throwable t) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            if (LOG.isTraceEnabled()) {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>            }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.396"></a>
-<span class="sourceLineNo">397</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.399"></a>
-<span class="sourceLineNo">400</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.403"></a>
-<span class="sourceLineNo">404</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>              + this.walEditsStopOffset);<a name="line.405"></a>
-<span class="sourceLineNo">406</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        }<a name="line.407"></a>
-<span class="sourceLineNo">408</span>      } catch (EOFException eof) {<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        if (originalPosition &lt; 0) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>          if (LOG.isTraceEnabled()) {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position because originalPosition is negative. last offset=" + this.inputStream.getPos(), eof);<a name="line.412"></a>
-<span class="sourceLineNo">413</span>          }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>          throw eof;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>        }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        // Else restore our position to original location in hope that next time through we will<a name="line.416"></a>
-<span class="sourceLineNo">417</span>        // read successfully.<a name="line.417"></a>
-<span class="sourceLineNo">418</span>        if (LOG.isTraceEnabled()) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>          LOG.trace("Encountered a malformed edit, seeking back to last good position in file, from "+ inputStream.getPos()+" to " + originalPosition, eof);<a name="line.419"></a>
-<span class="sourceLineNo">420</span>        }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        seekOnFs(originalPosition);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        return false;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>      return true;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
-<span class="sourceLineNo">426</span>  }<a name="line.426"></a>
-<span class="sourceLineNo">427</span><a name="line.427"></a>
-<span class="sourceLineNo">428</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    IOException ioEx = null;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    if (ex instanceof EOFException) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      return (EOFException)ex;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    } else if (ex instanceof IOException) {<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      ioEx = (IOException)ex;<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    } else if (ex instanceof RuntimeException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      ioEx = (IOException)ex.getCause();<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    if (ioEx != null) {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      return null;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    return null;<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  @Override<a name="line.447"></a>
-<span class="sourceLineNo">448</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    this.inputStream.seek(pos);<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>}<a name="line.451"></a>
+<span class="sourceLineNo">343</span>      boolean resetPosition = false;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      try {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        long available = -1;<a name="line.345"></a>
+<span class="sourceLineNo">346</span>        try {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>          int firstByte = this.inputStream.read();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>          if (firstByte == -1) {<a name="line.348"></a>
+<span class="sourceLineNo">349</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>          }<a name="line.350"></a>
+<span class="sourceLineNo">351</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.352"></a>
+<span class="sourceLineNo">353</span>          available = this.inputStream.available();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.355"></a>
+<span class="sourceLineNo">356</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.356"></a>
+<span class="sourceLineNo">357</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.357"></a>
+<span class="sourceLineNo">358</span>          }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.359"></a>
+<span class="sourceLineNo">360</span>            (int)size);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          resetPosition = true;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.363"></a>
+<span class="sourceLineNo">364</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.364"></a>
+<span class="sourceLineNo">365</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (!builder.isInitialized()) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.368"></a>
+<span class="sourceLineNo">369</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.369"></a>
+<span class="sourceLineNo">370</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.370"></a>
+<span class="sourceLineNo">371</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        }<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        WALKey walKey = builder.build();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          if (LOG.isTraceEnabled()) {<a name="line.376"></a>
+<span class="sourceLineNo">377</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.377"></a>
+<span class="sourceLineNo">378</span>                this.inputStream.getPos());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          }<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          seekOnFs(originalPosition);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          return false;<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        long posBefore = this.inputStream.getPos();<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        try {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          if (expectedCells != actualCells) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>            resetPosition = true;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        } catch (Exception ex) {<a name="line.391"></a>
+<span class="sourceLineNo">392</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.392"></a>
+<span class="sourceLineNo">393</span>          try {<a name="line.393"></a>
+<span class="sourceLineNo">394</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.394"></a>
+<span class="sourceLineNo">395</span>          } catch (Throwable t) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>            if (LOG.isTraceEnabled()) {<a name="line.396"></a>
+<span class="sourceLineNo">397</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>            }<a name="line.398"></a>
+<span class="sourceLineNo">399</span>          }<a name="line.399"></a>
+<span class="sourceLineNo">400</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.400"></a>
+<span class="sourceLineNo">401</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.401"></a>
+<span class="sourceLineNo">402</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.402"></a>
+<span class="sourceLineNo">403</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.403"></a>
+<span class="sourceLineNo">404</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        }<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.406"></a>
+<span class="sourceLineNo">407</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.407"></a>
+<span class="sourceLineNo">408</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.408"></a>
+<span class="sourceLineNo">409</span>              + this.walEditsStopOffset);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      } catch (EOFException eof) {<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        if (originalPosition &lt; 0) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>          if (LOG.isTraceEnabled()) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position "<a name="line.416"></a>
+<span class="sourceLineNo">417</span>                + "because originalPosition is negative. last offset="<a name="line.417"></a>
+<span class="sourceLineNo">418</span>                + this.inputStream.getPos(), eof);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>          }<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          throw eof;<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>        // If stuck at the same place and we got and exception, lets go back at the beginning.<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        if (inputStream.getPos() == originalPosition &amp;&amp; resetPosition) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>          if (LOG.isTraceEnabled()) {<a name="line.424"></a>
+<span class="sourceLineNo">425</span>            LOG.trace("Encountered a malformed edit, seeking to the beginning of the WAL since "<a name="line.425"></a>
+<span class="sourceLineNo">426</span>                + "current position and original position match at " + originalPosition);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>          }<a name="line.427"></a>
+<span class="sourceLineNo">428</span>          seekOnFs(0);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>        } else {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>          // Else restore our position to original location in hope that next time through we will<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          // read successfully.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          if (LOG.isTraceEnabled()) {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>            LOG.trace("Encountered a malformed edit, seeking back to last good position in file, "<a name="line.433"></a>
+<span class="sourceLineNo">434</span>                + "from " + inputStream.getPos()+" to " + originalPosition, eof);<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          }<a name="line.435"></a>
+<span class="sourceLineNo">436</span>          seekOnFs(originalPosition);<a name="line.436"></a>
+<span class="sourceLineNo">437</span>        }<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        return false;<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      return true;<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>  }<a name="line.442"></a>
+<span class="sourceLineNo">443</span><a name="line.443"></a>
+<span class="sourceLineNo">444</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    IOException ioEx = null;<a name="line.447"></a>
+<span class="sourceLineNo">448</span>    if (ex instanceof EOFException) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      return (EOFException)ex;<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    } else if (ex instanceof IOException) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      ioEx = (IOException)ex;<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    } else if (ex instanceof RuntimeException<a name="line.452"></a>
+<span class="sourceLineNo">453</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      ioEx = (IOException)ex.getCause();<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    }<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    if (ioEx != null) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.457"></a>
+<span class="sourceLineNo">458</span>      return null;<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    }<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    return null;<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  }<a name="line.461"></a>
+<span class="sourceLineNo">462</span><a name="line.462"></a>
+<span class="sourceLineNo">463</span>  @Override<a name="line.463"></a>
+<span class="sourceLineNo">464</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    this.inputStream.seek(pos);<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span>}<a name="line.467"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html
index 62e604e..0a58fc2 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html
@@ -348,115 +348,131 @@
 <span class="sourceLineNo">340</span>      }<a name="line.340"></a>
 <span class="sourceLineNo">341</span>      WALKey.Builder builder = WALKey.newBuilder();<a name="line.341"></a>
 <span class="sourceLineNo">342</span>      long size = 0;<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      try {<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        long available = -1;<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        try {<a name="line.345"></a>
-<span class="sourceLineNo">346</span>          int firstByte = this.inputStream.read();<a name="line.346"></a>
-<span class="sourceLineNo">347</span>          if (firstByte == -1) {<a name="line.347"></a>
-<span class="sourceLineNo">348</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>          }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.350"></a>
-<span class="sourceLineNo">351</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          available = this.inputStream.available();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.354"></a>
-<span class="sourceLineNo">355</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.355"></a>
-<span class="sourceLineNo">356</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.356"></a>
-<span class="sourceLineNo">357</span>          }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.358"></a>
-<span class="sourceLineNo">359</span>            (int)size);<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.361"></a>
-<span class="sourceLineNo">362</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.362"></a>
-<span class="sourceLineNo">363</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        }<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        if (!builder.isInitialized()) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.367"></a>
-<span class="sourceLineNo">368</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.368"></a>
-<span class="sourceLineNo">369</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.369"></a>
-<span class="sourceLineNo">370</span>        }<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        WALKey walKey = builder.build();<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.373"></a>
-<span class="sourceLineNo">374</span>          if (LOG.isTraceEnabled()) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.375"></a>
-<span class="sourceLineNo">376</span>                this.inputStream.getPos());<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          continue;<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        long posBefore = this.inputStream.getPos();<a name="line.381"></a>
-<span class="sourceLineNo">382</span>        try {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          if (expectedCells != actualCells) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        } catch (Exception ex) {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.388"></a>
-<span class="sourceLineNo">389</span>          try {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.390"></a>
-<span class="sourceLineNo">391</span>          } catch (Throwable t) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            if (LOG.isTraceEnabled()) {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>            }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.396"></a>
-<span class="sourceLineNo">397</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.399"></a>
-<span class="sourceLineNo">400</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.403"></a>
-<span class="sourceLineNo">404</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>              + this.walEditsStopOffset);<a name="line.405"></a>
-<span class="sourceLineNo">406</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        }<a name="line.407"></a>
-<span class="sourceLineNo">408</span>      } catch (EOFException eof) {<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        if (originalPosition &lt; 0) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>          if (LOG.isTraceEnabled()) {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position because originalPosition is negative. last offset=" + this.inputStream.getPos(), eof);<a name="line.412"></a>
-<span class="sourceLineNo">413</span>          }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>          throw eof;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>        }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        // Else restore our position to original location in hope that next time through we will<a name="line.416"></a>
-<span class="sourceLineNo">417</span>        // read successfully.<a name="line.417"></a>
-<span class="sourceLineNo">418</span>        if (LOG.isTraceEnabled()) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>          LOG.trace("Encountered a malformed edit, seeking back to last good position in file, from "+ inputStream.getPos()+" to " + originalPosition, eof);<a name="line.419"></a>
-<span class="sourceLineNo">420</span>        }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        seekOnFs(originalPosition);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        return false;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>      return true;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
-<span class="sourceLineNo">426</span>  }<a name="line.426"></a>
-<span class="sourceLineNo">427</span><a name="line.427"></a>
-<span class="sourceLineNo">428</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    IOException ioEx = null;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    if (ex instanceof EOFException) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      return (EOFException)ex;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    } else if (ex instanceof IOException) {<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      ioEx = (IOException)ex;<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    } else if (ex instanceof RuntimeException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      ioEx = (IOException)ex.getCause();<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    if (ioEx != null) {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      return null;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    return null;<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  @Override<a name="line.447"></a>
-<span class="sourceLineNo">448</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    this.inputStream.seek(pos);<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>}<a name="line.451"></a>
+<span class="sourceLineNo">343</span>      boolean resetPosition = false;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      try {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        long available = -1;<a name="line.345"></a>
+<span class="sourceLineNo">346</span>        try {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>          int firstByte = this.inputStream.read();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>          if (firstByte == -1) {<a name="line.348"></a>
+<span class="sourceLineNo">349</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>          }<a name="line.350"></a>
+<span class="sourceLineNo">351</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.352"></a>
+<span class="sourceLineNo">353</span>          available = this.inputStream.available();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.355"></a>
+<span class="sourceLineNo">356</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.356"></a>
+<span class="sourceLineNo">357</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.357"></a>
+<span class="sourceLineNo">358</span>          }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.359"></a>
+<span class="sourceLineNo">360</span>            (int)size);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          resetPosition = true;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.363"></a>
+<span class="sourceLineNo">364</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.364"></a>
+<span class="sourceLineNo">365</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (!builder.isInitialized()) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.368"></a>
+<span class="sourceLineNo">369</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.369"></a>
+<span class="sourceLineNo">370</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.370"></a>
+<span class="sourceLineNo">371</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        }<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        WALKey walKey = builder.build();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          if (LOG.isTraceEnabled()) {<a name="line.376"></a>
+<span class="sourceLineNo">377</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.377"></a>
+<span class="sourceLineNo">378</span>                this.inputStream.getPos());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          }<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          seekOnFs(originalPosition);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          return false;<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        long posBefore = this.inputStream.getPos();<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        try {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          if (expectedCells != actualCells) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>            resetPosition = true;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        } catch (Exception ex) {<a name="line.391"></a>
+<span class="sourceLineNo">392</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.392"></a>
+<span class="sourceLineNo">393</span>          try {<a name="line.393"></a>
+<span class="sourceLineNo">394</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.394"></a>
+<span class="sourceLineNo">395</span>          } catch (Throwable t) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>            if (LOG.isTraceEnabled()) {<a name="line.396"></a>
+<span class="sourceLineNo">397</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>            }<a name="line.398"></a>
+<span class="sourceLineNo">399</span>          }<a name="line.399"></a>
+<span class="sourceLineNo">400</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.400"></a>
+<span class="sourceLineNo">401</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.401"></a>
+<span class="sourceLineNo">402</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.402"></a>
+<span class="sourceLineNo">403</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.403"></a>
+<span class="sourceLineNo">404</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        }<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.406"></a>
+<span class="sourceLineNo">407</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.407"></a>
+<span class="sourceLineNo">408</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.408"></a>
+<span class="sourceLineNo">409</span>              + this.walEditsStopOffset);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      } catch (EOFException eof) {<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        if (originalPosition &lt; 0) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>          if (LOG.isTraceEnabled()) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position "<a name="line.416"></a>
+<span class="sourceLineNo">417</span>                + "because originalPosition is negative. last offset="<a name="line.417"></a>
+<span class="sourceLineNo">418</span>                + this.inputStream.getPos(), eof);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>          }<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          throw eof;<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>        // If stuck at the same place and we got and exception, lets go back at the beginning.<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        if (inputStream.getPos() == originalPosition &amp;&amp; resetPosition) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>          if (LOG.isTraceEnabled()) {<a name="line.424"></a>
+<span class="sourceLineNo">425</span>            LOG.trace("Encountered a malformed edit, seeking to the beginning of the WAL since "<a name="line.425"></a>
+<span class="sourceLineNo">426</span>                + "current position and original position match at " + originalPosition);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>          }<a name="line.427"></a>
+<span class="sourceLineNo">428</span>          seekOnFs(0);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>        } else {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>          // Else restore our position to original location in hope that next time through we will<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          // read successfully.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          if (LOG.isTraceEnabled()) {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>            LOG.trace("Encountered a malformed edit, seeking back to last good position in file, "<a name="line.433"></a>
+<span class="sourceLineNo">434</span>                + "from " + inputStream.getPos()+" to " + originalPosition, eof);<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          }<a name="line.435"></a>
+<span class="sourceLineNo">436</span>          seekOnFs(originalPosition);<a name="line.436"></a>
+<span class="sourceLineNo">437</span>        }<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        return false;<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      return true;<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>  }<a name="line.442"></a>
+<span class="sourceLineNo">443</span><a name="line.443"></a>
+<span class="sourceLineNo">444</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    IOException ioEx = null;<a name="line.447"></a>
+<span class="sourceLineNo">448</span>    if (ex instanceof EOFException) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      return (EOFException)ex;<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    } else if (ex instanceof IOException) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      ioEx = (IOException)ex;<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    } else if (ex instanceof RuntimeException<a name="line.452"></a>
+<span class="sourceLineNo">453</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      ioEx = (IOException)ex.getCause();<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    }<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    if (ioEx != null) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.457"></a>
+<span class="sourceLineNo">458</span>      return null;<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    }<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    return null;<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  }<a name="line.461"></a>
+<span class="sourceLineNo">462</span><a name="line.462"></a>
+<span class="sourceLineNo">463</span>  @Override<a name="line.463"></a>
+<span class="sourceLineNo">464</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    this.inputStream.seek(pos);<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span>}<a name="line.467"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
index 62e604e..0a58fc2 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.html
@@ -348,115 +348,131 @@
 <span class="sourceLineNo">340</span>      }<a name="line.340"></a>
 <span class="sourceLineNo">341</span>      WALKey.Builder builder = WALKey.newBuilder();<a name="line.341"></a>
 <span class="sourceLineNo">342</span>      long size = 0;<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      try {<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        long available = -1;<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        try {<a name="line.345"></a>
-<span class="sourceLineNo">346</span>          int firstByte = this.inputStream.read();<a name="line.346"></a>
-<span class="sourceLineNo">347</span>          if (firstByte == -1) {<a name="line.347"></a>
-<span class="sourceLineNo">348</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>          }<a name="line.349"></a>
-<span class="sourceLineNo">350</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.350"></a>
-<span class="sourceLineNo">351</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          available = this.inputStream.available();<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.354"></a>
-<span class="sourceLineNo">355</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.355"></a>
-<span class="sourceLineNo">356</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.356"></a>
-<span class="sourceLineNo">357</span>          }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.358"></a>
-<span class="sourceLineNo">359</span>            (int)size);<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.361"></a>
-<span class="sourceLineNo">362</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.362"></a>
-<span class="sourceLineNo">363</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        }<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        if (!builder.isInitialized()) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.366"></a>
-<span class="sourceLineNo">367</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.367"></a>
-<span class="sourceLineNo">368</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.368"></a>
-<span class="sourceLineNo">369</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.369"></a>
-<span class="sourceLineNo">370</span>        }<a name="line.370"></a>
-<span class="sourceLineNo">371</span>        WALKey walKey = builder.build();<a name="line.371"></a>
-<span class="sourceLineNo">372</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.373"></a>
-<span class="sourceLineNo">374</span>          if (LOG.isTraceEnabled()) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.375"></a>
-<span class="sourceLineNo">376</span>                this.inputStream.getPos());<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          }<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          continue;<a name="line.378"></a>
-<span class="sourceLineNo">379</span>        }<a name="line.379"></a>
-<span class="sourceLineNo">380</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.380"></a>
-<span class="sourceLineNo">381</span>        long posBefore = this.inputStream.getPos();<a name="line.381"></a>
-<span class="sourceLineNo">382</span>        try {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          if (expectedCells != actualCells) {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          }<a name="line.386"></a>
-<span class="sourceLineNo">387</span>        } catch (Exception ex) {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.388"></a>
-<span class="sourceLineNo">389</span>          try {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.390"></a>
-<span class="sourceLineNo">391</span>          } catch (Throwable t) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            if (LOG.isTraceEnabled()) {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>            }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.396"></a>
-<span class="sourceLineNo">397</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.399"></a>
-<span class="sourceLineNo">400</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>        }<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.403"></a>
-<span class="sourceLineNo">404</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.404"></a>
-<span class="sourceLineNo">405</span>              + this.walEditsStopOffset);<a name="line.405"></a>
-<span class="sourceLineNo">406</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        }<a name="line.407"></a>
-<span class="sourceLineNo">408</span>      } catch (EOFException eof) {<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        if (originalPosition &lt; 0) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>          if (LOG.isTraceEnabled()) {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position because originalPosition is negative. last offset=" + this.inputStream.getPos(), eof);<a name="line.412"></a>
-<span class="sourceLineNo">413</span>          }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>          throw eof;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>        }<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        // Else restore our position to original location in hope that next time through we will<a name="line.416"></a>
-<span class="sourceLineNo">417</span>        // read successfully.<a name="line.417"></a>
-<span class="sourceLineNo">418</span>        if (LOG.isTraceEnabled()) {<a name="line.418"></a>
-<span class="sourceLineNo">419</span>          LOG.trace("Encountered a malformed edit, seeking back to last good position in file, from "+ inputStream.getPos()+" to " + originalPosition, eof);<a name="line.419"></a>
-<span class="sourceLineNo">420</span>        }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        seekOnFs(originalPosition);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        return false;<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>      return true;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
-<span class="sourceLineNo">426</span>  }<a name="line.426"></a>
-<span class="sourceLineNo">427</span><a name="line.427"></a>
-<span class="sourceLineNo">428</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    IOException ioEx = null;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    if (ex instanceof EOFException) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      return (EOFException)ex;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    } else if (ex instanceof IOException) {<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      ioEx = (IOException)ex;<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    } else if (ex instanceof RuntimeException<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      ioEx = (IOException)ex.getCause();<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    }<a name="line.439"></a>
-<span class="sourceLineNo">440</span>    if (ioEx != null) {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      return null;<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    return null;<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  }<a name="line.445"></a>
-<span class="sourceLineNo">446</span><a name="line.446"></a>
-<span class="sourceLineNo">447</span>  @Override<a name="line.447"></a>
-<span class="sourceLineNo">448</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    this.inputStream.seek(pos);<a name="line.449"></a>
-<span class="sourceLineNo">450</span>  }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>}<a name="line.451"></a>
+<span class="sourceLineNo">343</span>      boolean resetPosition = false;<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      try {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>        long available = -1;<a name="line.345"></a>
+<span class="sourceLineNo">346</span>        try {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>          int firstByte = this.inputStream.read();<a name="line.347"></a>
+<span class="sourceLineNo">348</span>          if (firstByte == -1) {<a name="line.348"></a>
+<span class="sourceLineNo">349</span>            throw new EOFException("First byte is negative at offset " + originalPosition);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>          }<a name="line.350"></a>
+<span class="sourceLineNo">351</span>          size = CodedInputStream.readRawVarint32(firstByte, this.inputStream);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>          // available may be &lt; 0 on local fs for instance.  If so, can't depend on it.<a name="line.352"></a>
+<span class="sourceLineNo">353</span>          available = this.inputStream.available();<a name="line.353"></a>
+<span class="sourceLineNo">354</span>          if (available &gt; 0 &amp;&amp; available &lt; size) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>            throw new EOFException("Available stream not enough for edit, " +<a name="line.355"></a>
+<span class="sourceLineNo">356</span>                "inputStream.available()= " + this.inputStream.available() + ", " +<a name="line.356"></a>
+<span class="sourceLineNo">357</span>                "entry size= " + size + " at offset = " + this.inputStream.getPos());<a name="line.357"></a>
+<span class="sourceLineNo">358</span>          }<a name="line.358"></a>
+<span class="sourceLineNo">359</span>          ProtobufUtil.mergeFrom(builder, ByteStreams.limit(this.inputStream, size),<a name="line.359"></a>
+<span class="sourceLineNo">360</span>            (int)size);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        } catch (InvalidProtocolBufferException ipbe) {<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          resetPosition = true;<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          throw (EOFException) new EOFException("Invalid PB, EOF? Ignoring; originalPosition=" +<a name="line.363"></a>
+<span class="sourceLineNo">364</span>            originalPosition + ", currentPosition=" + this.inputStream.getPos() +<a name="line.364"></a>
+<span class="sourceLineNo">365</span>            ", messageSize=" + size + ", currentAvailable=" + available).initCause(ipbe);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (!builder.isInitialized()) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          // TODO: not clear if we should try to recover from corrupt PB that looks semi-legit.<a name="line.368"></a>
+<span class="sourceLineNo">369</span>          //       If we can get the KV count, we could, theoretically, try to get next record.<a name="line.369"></a>
+<span class="sourceLineNo">370</span>          throw new EOFException("Partial PB while reading WAL, " +<a name="line.370"></a>
+<span class="sourceLineNo">371</span>              "probably an unexpected EOF, ignoring. current offset=" + this.inputStream.getPos());<a name="line.371"></a>
+<span class="sourceLineNo">372</span>        }<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        WALKey walKey = builder.build();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>        entry.getKey().readFieldsFromPb(walKey, this.byteStringUncompressor);<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        if (!walKey.hasFollowingKvCount() || 0 == walKey.getFollowingKvCount()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          if (LOG.isTraceEnabled()) {<a name="line.376"></a>
+<span class="sourceLineNo">377</span>            LOG.trace("WALKey has no KVs that follow it; trying the next one. current offset=" +<a name="line.377"></a>
+<span class="sourceLineNo">378</span>                this.inputStream.getPos());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          }<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          seekOnFs(originalPosition);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          return false;<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>        int expectedCells = walKey.getFollowingKvCount();<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        long posBefore = this.inputStream.getPos();<a name="line.384"></a>
+<span class="sourceLineNo">385</span>        try {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>          int actualCells = entry.getEdit().readFromCells(cellDecoder, expectedCells);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>          if (expectedCells != actualCells) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>            resetPosition = true;<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            throw new EOFException("Only read " + actualCells); // other info added in catch<a name="line.389"></a>
+<span class="sourceLineNo">390</span>          }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        } catch (Exception ex) {<a name="line.391"></a>
+<span class="sourceLineNo">392</span>          String posAfterStr = "&lt;unknown&gt;";<a name="line.392"></a>
+<span class="sourceLineNo">393</span>          try {<a name="line.393"></a>
+<span class="sourceLineNo">394</span>            posAfterStr = this.inputStream.getPos() + "";<a name="line.394"></a>
+<span class="sourceLineNo">395</span>          } catch (Throwable t) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>            if (LOG.isTraceEnabled()) {<a name="line.396"></a>
+<span class="sourceLineNo">397</span>              LOG.trace("Error getting pos for error message - ignoring", t);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>            }<a name="line.398"></a>
+<span class="sourceLineNo">399</span>          }<a name="line.399"></a>
+<span class="sourceLineNo">400</span>          String message = " while reading " + expectedCells + " WAL KVs; started reading at "<a name="line.400"></a>
+<span class="sourceLineNo">401</span>              + posBefore + " and read up to " + posAfterStr;<a name="line.401"></a>
+<span class="sourceLineNo">402</span>          IOException realEofEx = extractHiddenEof(ex);<a name="line.402"></a>
+<span class="sourceLineNo">403</span>          throw (EOFException) new EOFException("EOF " + message).<a name="line.403"></a>
+<span class="sourceLineNo">404</span>              initCause(realEofEx != null ? realEofEx : ex);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        }<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        if (trailerPresent &amp;&amp; this.inputStream.getPos() &gt; this.walEditsStopOffset) {<a name="line.406"></a>
+<span class="sourceLineNo">407</span>          LOG.error("Read WALTrailer while reading WALEdits. wal: " + this.path<a name="line.407"></a>
+<span class="sourceLineNo">408</span>              + ", inputStream.getPos(): " + this.inputStream.getPos() + ", walEditsStopOffset: "<a name="line.408"></a>
+<span class="sourceLineNo">409</span>              + this.walEditsStopOffset);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          throw new EOFException("Read WALTrailer while reading WALEdits");<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      } catch (EOFException eof) {<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        // If originalPosition is &lt; 0, it is rubbish and we cannot use it (probably local fs)<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        if (originalPosition &lt; 0) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>          if (LOG.isTraceEnabled()) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>            LOG.trace("Encountered a malformed edit, but can't seek back to last good position "<a name="line.416"></a>
+<span class="sourceLineNo">417</span>                + "because originalPosition is negative. last offset="<a name="line.417"></a>
+<span class="sourceLineNo">418</span>                + this.inputStream.getPos(), eof);<a name="line.418"></a>
+<span class="sourceLineNo">419</span>          }<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          throw eof;<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>        // If stuck at the same place and we got and exception, lets go back at the beginning.<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        if (inputStream.getPos() == originalPosition &amp;&amp; resetPosition) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>          if (LOG.isTraceEnabled()) {<a name="line.424"></a>
+<span class="sourceLineNo">425</span>            LOG.trace("Encountered a malformed edit, seeking to the beginning of the WAL since "<a name="line.425"></a>
+<span class="sourceLineNo">426</span>                + "current position and original position match at " + originalPosition);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>          }<a name="line.427"></a>
+<span class="sourceLineNo">428</span>          seekOnFs(0);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>        } else {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>          // Else restore our position to original location in hope that next time through we will<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          // read successfully.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>          if (LOG.isTraceEnabled()) {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>            LOG.trace("Encountered a malformed edit, seeking back to last good position in file, "<a name="line.433"></a>
+<span class="sourceLineNo">434</span>                + "from " + inputStream.getPos()+" to " + originalPosition, eof);<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          }<a name="line.435"></a>
+<span class="sourceLineNo">436</span>          seekOnFs(originalPosition);<a name="line.436"></a>
+<span class="sourceLineNo">437</span>        }<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        return false;<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      return true;<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
+<span class="sourceLineNo">442</span>  }<a name="line.442"></a>
+<span class="sourceLineNo">443</span><a name="line.443"></a>
+<span class="sourceLineNo">444</span>  private IOException extractHiddenEof(Exception ex) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    // There are two problems we are dealing with here. Hadoop stream throws generic exception<a name="line.445"></a>
+<span class="sourceLineNo">446</span>    // for EOF, not EOFException; and scanner further hides it inside RuntimeException.<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    IOException ioEx = null;<a name="line.447"></a>
+<span class="sourceLineNo">448</span>    if (ex instanceof EOFException) {<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      return (EOFException)ex;<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    } else if (ex instanceof IOException) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      ioEx = (IOException)ex;<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    } else if (ex instanceof RuntimeException<a name="line.452"></a>
+<span class="sourceLineNo">453</span>        &amp;&amp; ex.getCause() != null &amp;&amp; ex.getCause() instanceof IOException) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      ioEx = (IOException)ex.getCause();<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    }<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    if (ioEx != null) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>      if (ioEx.getMessage().contains("EOF")) return ioEx;<a name="line.457"></a>
+<span class="sourceLineNo">458</span>      return null;<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    }<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    return null;<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  }<a name="line.461"></a>
+<span class="sourceLineNo">462</span><a name="line.462"></a>
+<span class="sourceLineNo">463</span>  @Override<a name="line.463"></a>
+<span class="sourceLineNo">464</span>  protected void seekOnFs(long pos) throws IOException {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    this.inputStream.seek(pos);<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span>}<a name="line.467"></a>
 
 
 


[32/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        break;<a name="line.432"></a>
+<span clas

<TRUNCATED>

[14/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.WriteRequestCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLineNo"

<TRUNCATED>

[22/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionCountSkewCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class

<TRUNCATED>

[29/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCostFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sourceLi

<TRUNCATED>

[11/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
index 083ab07..be28dfa 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.NodeFailoverWorker.html
@@ -31,54 +31,54 @@
 <span class="sourceLineNo">023</span>import java.util.Collection;<a name="line.23"></a>
 <span class="sourceLineNo">024</span>import java.util.Collections;<a name="line.24"></a>
 <span class="sourceLineNo">025</span>import java.util.HashMap;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.HashSet;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.Iterator;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import java.util.List;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import java.util.Map;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import java.util.NavigableSet;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import java.util.Set;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import java.util.SortedSet;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import java.util.TreeSet;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import java.util.UUID;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import java.util.concurrent.ConcurrentMap;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import java.util.concurrent.Future;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import java.util.concurrent.RejectedExecutionException;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import java.util.concurrent.TimeUnit;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import java.util.stream.Collectors;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.conf.Configuration;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.FileSystem;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.fs.Path;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.HConstants;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.Server;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.ServerName;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.TableName;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.63"></a>
-<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.67"></a>
-<span class="sourceLineNo">068</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.68"></a>
-<span class="sourceLineNo">069</span>import org.apache.zookeeper.KeeperException;<a name="line.69"></a>
-<span class="sourceLineNo">070</span>import org.slf4j.Logger;<a name="line.70"></a>
-<span class="sourceLineNo">071</span>import org.slf4j.LoggerFactory;<a name="line.71"></a>
-<span class="sourceLineNo">072</span><a name="line.72"></a>
-<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.73"></a>
+<span class="sourceLineNo">026</span>import java.util.Iterator;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.List;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.Map;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.NavigableSet;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import java.util.Set;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import java.util.SortedSet;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import java.util.TreeSet;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import java.util.UUID;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import java.util.concurrent.ConcurrentMap;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import java.util.concurrent.Future;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import java.util.concurrent.LinkedBlockingQueue;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import java.util.concurrent.RejectedExecutionException;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import java.util.concurrent.ThreadLocalRandom;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import java.util.concurrent.ThreadPoolExecutor;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import java.util.concurrent.TimeUnit;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import java.util.concurrent.atomic.AtomicLong;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import java.util.stream.Collectors;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.conf.Configuration;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.fs.FileSystem;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.Path;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.CompatibilitySingletonFactory;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.HConstants;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.Server;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.ServerName;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.TableName;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.replication.ReplicationException;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.replication.ReplicationListener;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.replication.ReplicationPeer;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.replication.ReplicationPeer.PeerState;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;<a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.replication.ReplicationPeerImpl;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.replication.ReplicationPeers;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.replication.ReplicationQueueInfo;<a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.replication.ReplicationQueueStorage;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.replication.ReplicationTracker;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.replication.ReplicationUtils;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.replication.SyncReplicationState;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.util.Pair;<a name="line.64"></a>
+<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.wal.SyncReplicationWALProvider;<a name="line.66"></a>
+<span class="sourceLineNo">067</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>import org.apache.zookeeper.KeeperException;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>import org.slf4j.Logger;<a name="line.69"></a>
+<span class="sourceLineNo">070</span>import org.slf4j.LoggerFactory;<a name="line.70"></a>
+<span class="sourceLineNo">071</span><a name="line.71"></a>
+<span class="sourceLineNo">072</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.com.google.common.collect.Sets;<a name="line.73"></a>
 <span class="sourceLineNo">074</span>import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;<a name="line.74"></a>
 <span class="sourceLineNo">075</span><a name="line.75"></a>
 <span class="sourceLineNo">076</span>/**<a name="line.76"></a>
@@ -156,7 +156,7 @@
 <span class="sourceLineNo">148</span>  private final Configuration conf;<a name="line.148"></a>
 <span class="sourceLineNo">149</span>  private final FileSystem fs;<a name="line.149"></a>
 <span class="sourceLineNo">150</span>  // The paths to the latest log of each wal group, for new coming peers<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private final Set&lt;Path&gt; latestPaths;<a name="line.151"></a>
+<span class="sourceLineNo">151</span>  private final Map&lt;String, Path&gt; latestPaths;<a name="line.151"></a>
 <span class="sourceLineNo">152</span>  // Path to the wals directories<a name="line.152"></a>
 <span class="sourceLineNo">153</span>  private final Path logDir;<a name="line.153"></a>
 <span class="sourceLineNo">154</span>  // Path to the wal archive<a name="line.154"></a>
@@ -224,7 +224,7 @@
 <span class="sourceLineNo">216</span>    tfb.setNameFormat("ReplicationExecutor-%d");<a name="line.216"></a>
 <span class="sourceLineNo">217</span>    tfb.setDaemon(true);<a name="line.217"></a>
 <span class="sourceLineNo">218</span>    this.executor.setThreadFactory(tfb.build());<a name="line.218"></a>
-<span class="sourceLineNo">219</span>    this.latestPaths = new HashSet&lt;Path&gt;();<a name="line.219"></a>
+<span class="sourceLineNo">219</span>    this.latestPaths = new HashMap&lt;&gt;();<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    this.replicationForBulkLoadDataEnabled = conf.getBoolean(<a name="line.220"></a>
 <span class="sourceLineNo">221</span>      HConstants.REPLICATION_BULKLOAD_ENABLE_KEY, HConstants.REPLICATION_BULKLOAD_ENABLE_DEFAULT);<a name="line.221"></a>
 <span class="sourceLineNo">222</span>    this.sleepForRetries = this.conf.getLong("replication.source.sync.sleepforretries", 1000);<a name="line.222"></a>
@@ -379,756 +379,754 @@
 <span class="sourceLineNo">371</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByGroup = new HashMap&lt;&gt;();<a name="line.371"></a>
 <span class="sourceLineNo">372</span>      this.walsById.put(peerId, walsByGroup);<a name="line.372"></a>
 <span class="sourceLineNo">373</span>      // Add the latest wal to that source's queue<a name="line.373"></a>
-<span class="sourceLineNo">374</span>      if (this.latestPaths.size() &gt; 0) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        for (Path logPath : latestPaths) {<a name="line.375"></a>
-<span class="sourceLineNo">376</span>          String name = logPath.getName();<a name="line.376"></a>
-<span class="sourceLineNo">377</span>          String walPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(name);<a name="line.377"></a>
-<span class="sourceLineNo">378</span>          NavigableSet&lt;String&gt; logs = new TreeSet&lt;&gt;();<a name="line.378"></a>
-<span class="sourceLineNo">379</span>          logs.add(name);<a name="line.379"></a>
-<span class="sourceLineNo">380</span>          walsByGroup.put(walPrefix, logs);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>          // Abort RS and throw exception to make add peer failed<a name="line.381"></a>
-<span class="sourceLineNo">382</span>          abortAndThrowIOExceptionWhenFail(<a name="line.382"></a>
-<span class="sourceLineNo">383</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, name));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>          src.enqueueLog(logPath);<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>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    if (peerConfig.isSyncReplication()) {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    }<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    src.startup();<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    return src;<a name="line.393"></a>
-<span class="sourceLineNo">394</span>  }<a name="line.394"></a>
-<span class="sourceLineNo">395</span><a name="line.395"></a>
-<span class="sourceLineNo">396</span>  /**<a name="line.396"></a>
-<span class="sourceLineNo">397</span>   * &lt;p&gt;<a name="line.397"></a>
-<span class="sourceLineNo">398</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.398"></a>
-<span class="sourceLineNo">399</span>   * &lt;/p&gt;<a name="line.399"></a>
-<span class="sourceLineNo">400</span>   * &lt;p&gt;<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.403"></a>
-<span class="sourceLineNo">404</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.404"></a>
-<span class="sourceLineNo">405</span>   * &lt;/p&gt;<a name="line.405"></a>
-<span class="sourceLineNo">406</span>   * &lt;p&gt;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>   * See HBASE-20426 for more details.<a name="line.407"></a>
-<span class="sourceLineNo">408</span>   * &lt;/p&gt;<a name="line.408"></a>
-<span class="sourceLineNo">409</span>   * @param peerId the id of the sync replication peer<a name="line.409"></a>
-<span class="sourceLineNo">410</span>   */<a name="line.410"></a>
-<span class="sourceLineNo">411</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    // walsById.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    ReplicationSourceInterface toRemove;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    synchronized (latestPaths) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      toRemove = sources.put(peerId, src);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      if (toRemove != null) {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        toRemove.terminate(terminateMessage);<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        toRemove.getSourceMetrics().clear();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      }<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.429"></a>
-<span class="sourceLineNo">430</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.430"></a>
-<span class="sourceLineNo">431</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.431"></a>
-<span class="sourceLineNo">432</span>      // from the replication queue storage.<a name="line.432"></a>
-<span class="sourceLineNo">433</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    src.startup();<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      for (String wal : walsByGroup) {<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<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>    synchronized (walsById) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      wals.forEach((k, v) -&gt; {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        if (walsByGroup != null) {<a name="line.446"></a>
-<span class="sourceLineNo">447</span>          walsByGroup.removeAll(v);<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        }<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      });<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // simplify the logic.<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    synchronized (this.oldsources) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.455"></a>
-<span class="sourceLineNo">456</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.457"></a>
-<span class="sourceLineNo">458</span>          String queueId = oldSource.getQueueId();<a name="line.458"></a>
-<span class="sourceLineNo">459</span>          oldSource.terminate(terminateMessage);<a name="line.459"></a>
-<span class="sourceLineNo">460</span>          oldSource.getSourceMetrics().clear();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.461"></a>
-<span class="sourceLineNo">462</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.462"></a>
-<span class="sourceLineNo">463</span>          iter.remove();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        }<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    }<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /**<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.470"></a>
-<span class="sourceLineNo">471</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.471"></a>
-<span class="sourceLineNo">472</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.472"></a>
-<span class="sourceLineNo">473</span>   * @param peerId the id of the replication peer<a name="line.473"></a>
-<span class="sourceLineNo">474</span>   */<a name="line.474"></a>
-<span class="sourceLineNo">475</span>  public void refreshSources(String peerId) throws IOException {<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    String terminateMessage = "Peer " + peerId +<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.480"></a>
-<span class="sourceLineNo">481</span>    synchronized (this.latestPaths) {<a name="line.481"></a>
-<span class="sourceLineNo">482</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.482"></a>
-<span class="sourceLineNo">483</span>      if (toRemove != null) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.484"></a>
-<span class="sourceLineNo">485</span>        toRemove.terminate(terminateMessage);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      }<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      }<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    }<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    src.startup();<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.495"></a>
-<span class="sourceLineNo">496</span>    synchronized (this.oldsources) {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.500"></a>
-<span class="sourceLineNo">501</span>          oldSource.terminate(terminateMessage);<a name="line.501"></a>
-<span class="sourceLineNo">502</span>          this.oldsources.remove(oldSource);<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        }<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      }<a name="line.504"></a>
-<span class="sourceLineNo">505</span>      for (String queueId : previousQueueIds) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.506"></a>
-<span class="sourceLineNo">507</span>        this.oldsources.add(replicationSource);<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        toStartup.add(replicationSource);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>      }<a name="line.512"></a>
-<span class="sourceLineNo">513</span>    }<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      replicationSource.startup();<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    }<a name="line.516"></a>
-<span class="sourceLineNo">517</span>  }<a name="line.517"></a>
-<span class="sourceLineNo">518</span><a name="line.518"></a>
-<span class="sourceLineNo">519</span>  /**<a name="line.519"></a>
-<span class="sourceLineNo">520</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.520"></a>
-<span class="sourceLineNo">521</span>   * @param src source to clear<a name="line.521"></a>
-<span class="sourceLineNo">522</span>   */<a name="line.522"></a>
-<span class="sourceLineNo">523</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    if (!this.oldsources.remove(src)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>      return false;<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    }<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    // Delete queue from storage and memory<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    deleteQueue(src.getQueueId());<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    return true;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>  }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    synchronized (oldsources) {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      if (!removeRecoveredSource(src)) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.540"></a>
-<span class="sourceLineNo">541</span>      src.getStats());<a name="line.541"></a>
-<span class="sourceLineNo">542</span>  }<a name="line.542"></a>
-<span class="sourceLineNo">543</span><a name="line.543"></a>
-<span class="sourceLineNo">544</span>  /**<a name="line.544"></a>
-<span class="sourceLineNo">545</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.545"></a>
-<span class="sourceLineNo">546</span>   * @param src source to clear<a name="line.546"></a>
-<span class="sourceLineNo">547</span>   */<a name="line.547"></a>
-<span class="sourceLineNo">548</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    this.sources.remove(src.getPeerId());<a name="line.550"></a>
-<span class="sourceLineNo">551</span>    // Delete queue from storage and memory<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    deleteQueue(src.getQueueId());<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    this.walsById.remove(src.getQueueId());<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  /**<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * Delete a complete queue of wals associated with a replication source<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @param queueId the id of replication queue to delete<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   */<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  private void deleteQueue(String queueId) {<a name="line.561"></a>
-<span class="sourceLineNo">562</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  }<a name="line.563"></a>
-<span class="sourceLineNo">564</span><a name="line.564"></a>
-<span class="sourceLineNo">565</span>  @FunctionalInterface<a name="line.565"></a>
-<span class="sourceLineNo">566</span>  private interface ReplicationQueueOperation {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    void exec() throws ReplicationException;<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>  /**<a name="line.570"></a>
-<span class="sourceLineNo">571</span>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.571"></a>
-<span class="sourceLineNo">572</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   */<a name="line.573"></a>
-<span class="sourceLineNo">574</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    try {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>      op.exec();<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    } catch (ReplicationException e) {<a name="line.577"></a>
-<span class="sourceLineNo">578</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.578"></a>
-<span class="sourceLineNo">579</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.579"></a>
-<span class="sourceLineNo">580</span>          .getCause() instanceof InterruptedException) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>        throw new RuntimeException(<a name="line.581"></a>
-<span class="sourceLineNo">582</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      }<a name="line.583"></a>
-<span class="sourceLineNo">584</span>      server.abort("Failed to operate on replication queue", e);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    }<a name="line.585"></a>
-<span class="sourceLineNo">586</span>  }<a name="line.586"></a>
-<span class="sourceLineNo">587</span><a name="line.587"></a>
-<span class="sourceLineNo">588</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    try {<a name="line.589"></a>
-<span class="sourceLineNo">590</span>      op.exec();<a name="line.590"></a>
-<span class="sourceLineNo">591</span>    } catch (ReplicationException e) {<a name="line.591"></a>
-<span class="sourceLineNo">592</span>      server.abort("Failed to operate on replication queue", e);<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    }<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>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>    try {<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      op.exec();<a name="line.598"></a>
-<span class="sourceLineNo">599</span>    } catch (ReplicationException e) {<a name="line.599"></a>
-<span class="sourceLineNo">600</span>      throw new IOException(e);<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    }<a name="line.601"></a>
-<span class="sourceLineNo">602</span>  }<a name="line.602"></a>
-<span class="sourceLineNo">603</span><a name="line.603"></a>
-<span class="sourceLineNo">604</span>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    try {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      op.exec();<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    } catch (ReplicationException e) {<a name="line.607"></a>
-<span class="sourceLineNo">608</span>      server.abort("Failed to operate on replication queue", e);<a name="line.608"></a>
-<span class="sourceLineNo">609</span>      throw new IOException(e);<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><a name="line.612"></a>
-<span class="sourceLineNo">613</span>  /**<a name="line.613"></a>
-<span class="sourceLineNo">614</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.614"></a>
-<span class="sourceLineNo">615</span>   * replication queue.<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * @param source the replication source<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.617"></a>
-<span class="sourceLineNo">618</span>   */<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.619"></a>
-<span class="sourceLineNo">620</span>      WALEntryBatch entryBatch) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.622"></a>
-<span class="sourceLineNo">623</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.623"></a>
-<span class="sourceLineNo">624</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<a name="line.624"></a>
-<span class="sourceLineNo">625</span>  }<a name="line.625"></a>
-<span class="sourceLineNo">626</span><a name="line.626"></a>
-<span class="sourceLineNo">627</span>  /**<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.628"></a>
-<span class="sourceLineNo">629</span>   * file is closed and has no more entries.<a name="line.629"></a>
-<span class="sourceLineNo">630</span>   * @param log Path to the log<a name="line.630"></a>
-<span class="sourceLineNo">631</span>   * @param inclusive whether we should also remove the given log file<a name="line.631"></a>
-<span class="sourceLineNo">632</span>   * @param source the replication source<a name="line.632"></a>
-<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
-<span class="sourceLineNo">634</span>  @VisibleForTesting<a name="line.634"></a>
-<span class="sourceLineNo">635</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    if (source.isRecovered()) {<a name="line.637"></a>
-<span class="sourceLineNo">638</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.638"></a>
-<span class="sourceLineNo">639</span>      if (wals != null) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.640"></a>
-<span class="sourceLineNo">641</span>        if (walsToRemove.isEmpty()) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>          return;<a name="line.642"></a>
-<span class="sourceLineNo">643</span>        }<a name="line.643"></a>
-<span class="sourceLineNo">644</span>        cleanOldLogs(walsToRemove, source);<a name="line.644"></a>
-<span class="sourceLineNo">645</span>        walsToRemove.clear();<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      }<a name="line.646"></a>
-<span class="sourceLineNo">647</span>    } else {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; wals;<a name="line.648"></a>
-<span class="sourceLineNo">649</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.649"></a>
-<span class="sourceLineNo">650</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      synchronized (this.walsById) {<a name="line.651"></a>
-<span class="sourceLineNo">652</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.652"></a>
-<span class="sourceLineNo">653</span>        if (wals == null) {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>          return;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>        }<a name="line.655"></a>
-<span class="sourceLineNo">656</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>        if (walsToRemove.isEmpty()) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>          return;<a name="line.658"></a>
-<span class="sourceLineNo">659</span>        }<a name="line.659"></a>
-<span class="sourceLineNo">660</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.660"></a>
-<span class="sourceLineNo">661</span>      }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      // the lock to avoid block preLogRoll<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      cleanOldLogs(walsToRemove, source);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>      // now let's remove the files in the set<a name="line.666"></a>
-<span class="sourceLineNo">667</span>      synchronized (this.walsById) {<a name="line.667"></a>
-<span class="sourceLineNo">668</span>        wals.removeAll(walsToRemove);<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      }<a name="line.669"></a>
-<span class="sourceLineNo">670</span>    }<a name="line.670"></a>
-<span class="sourceLineNo">671</span>  }<a name="line.671"></a>
-<span class="sourceLineNo">672</span><a name="line.672"></a>
-<span class="sourceLineNo">673</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.673"></a>
-<span class="sourceLineNo">674</span>      throws IOException {<a name="line.674"></a>
-<span class="sourceLineNo">675</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    for (String wal : wals) {<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      try {<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.680"></a>
-<span class="sourceLineNo">681</span>          throw new IOException("Can not delete " + walFile);<a name="line.681"></a>
-<span class="sourceLineNo">682</span>        }<a name="line.682"></a>
-<span class="sourceLineNo">683</span>      } catch (FileNotFoundException e) {<a name="line.683"></a>
-<span class="sourceLineNo">684</span>        // Just ignore since this means the file has already been deleted.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.686"></a>
-<span class="sourceLineNo">687</span>        // FileSystem.delete, and also catch FNFE.<a name="line.687"></a>
-<span class="sourceLineNo">688</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<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>  }<a name="line.691"></a>
-<span class="sourceLineNo">692</span><a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void cleanOldLogs(NavigableSet&lt;String&gt; wals, ReplicationSourceInterface source) {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    LOG.debug("Removing {} logs in the list: {}", wals.size(), wals);<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    // The intention here is that, we want to delete the remote wal files ASAP as it may effect the<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    // failover time if you want to transit the remote cluster from S to A. And the infinite retry<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    // is not a problem, as if we can not contact with the remote HDFS cluster, then usually we can<a name="line.697"></a>
-<span class="sourceLineNo">698</span>    // not contact with the HBase cluster either, so the replication will be blocked either.<a name="line.698"></a>
-<span class="sourceLineNo">699</span>    if (source.isSyncReplication()) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>      String peerId = source.getPeerId();<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      String remoteWALDir = source.getPeer().getPeerConfig().getRemoteWALDir();<a name="line.701"></a>
-<span class="sourceLineNo">702</span>      // Filter out the wals need to be removed from the remote directory. Its name should be the<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      // special format, and also, the peer id in its name should match the peer id for the<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      // replication source.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      List&lt;String&gt; remoteWals = wals.stream().filter(w -&gt; SyncReplicationWALProvider<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        .getSyncReplicationPeerIdFromWALName(w).map(peerId::equals).orElse(false))<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        .collect(Collectors.toList());<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.debug("Removing {} logs from remote dir {} in the list: {}", remoteWals.size(),<a name="line.708"></a>
-<span class="sourceLineNo">709</span>        remoteWALDir, remoteWals);<a name="line.709"></a>
-<span class="sourceLineNo">710</span>      if (!remoteWals.isEmpty()) {<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        for (int sleepMultiplier = 0;;) {<a name="line.711"></a>
-<span class="sourceLineNo">712</span>          try {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>            removeRemoteWALs(peerId, remoteWALDir, remoteWals);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>            break;<a name="line.714"></a>
-<span class="sourceLineNo">715</span>          } catch (IOException e) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>            LOG.warn("Failed to delete remote wals from remote dir {} for peer {}", remoteWALDir,<a name="line.716"></a>
-<span class="sourceLineNo">717</span>              peerId);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>          }<a name="line.718"></a>
-<span class="sourceLineNo">719</span>          if (!source.isSourceActive()) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>            // skip the following operations<a name="line.720"></a>
-<span class="sourceLineNo">721</span>            return;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>          }<a name="line.722"></a>
-<span class="sourceLineNo">723</span>          if (ReplicationUtils.sleepForRetries("Failed to delete remote wals", sleepForRetries,<a name="line.723"></a>
-<span class="sourceLineNo">724</span>            sleepMultiplier, maxRetriesMultiplier)) {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>            sleepMultiplier++;<a name="line.725"></a>
-<span class="sourceLineNo">726</span>          }<a name="line.726"></a>
-<span class="sourceLineNo">727</span>        }<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>    String queueId = source.getQueueId();<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    for (String wal : wals) {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      interruptOrAbortWhenFail(<a name="line.732"></a>
-<span class="sourceLineNo">733</span>        () -&gt; this.queueStorage.removeWAL(server.getServerName(), queueId, wal));<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    }<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  // public because of we call it in TestReplicationEmptyWALRecovery<a name="line.737"></a>
-<span class="sourceLineNo">738</span>  @VisibleForTesting<a name="line.738"></a>
-<span class="sourceLineNo">739</span>  public void preLogRoll(Path newLog) throws IOException {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>    String logName = newLog.getName();<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(logName);<a name="line.741"></a>
-<span class="sourceLineNo">742</span>    // synchronized on latestPaths to avoid the new open source miss the new log<a name="line.742"></a>
-<span class="sourceLineNo">743</span>    synchronized (this.latestPaths) {<a name="line.743"></a>
-<span class="sourceLineNo">744</span>      // Add log to queue storage<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      for (ReplicationSourceInterface source : this.sources.values()) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>        // If record log to queue storage failed, abort RS and throw exception to make log roll<a name="line.746"></a>
-<span class="sourceLineNo">747</span>        // failed<a name="line.747"></a>
-<span class="sourceLineNo">748</span>        abortAndThrowIOExceptionWhenFail(<a name="line.748"></a>
-<span class="sourceLineNo">749</span>          () -&gt; this.queueStorage.addWAL(server.getServerName(), source.getQueueId(), logName));<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      }<a name="line.750"></a>
-<span class="sourceLineNo">751</span><a name="line.751"></a>
-<span class="sourceLineNo">752</span>      // synchronized on walsById to avoid race with cleanOldLogs<a name="line.752"></a>
-<span class="sourceLineNo">753</span>      synchronized (this.walsById) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>        // Update walsById map<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        for (Map.Entry&lt;String, Map&lt;String, NavigableSet&lt;String&gt;&gt;&gt; entry : this.walsById<a name="line.755"></a>
-<span class="sourceLineNo">756</span>          .entrySet()) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>          String peerId = entry.getKey();<a name="line.757"></a>
-<span class="sourceLineNo">758</span>          Map&lt;String, NavigableSet&lt;String&gt;&gt; walsByPrefix = entry.getValue();<a name="line.758"></a>
-<span class="sourceLineNo">759</span>          boolean existingPrefix = false;<a name="line.759"></a>
-<span class="sourceLineNo">760</span>          for (Map.Entry&lt;String, NavigableSet&lt;String&gt;&gt; walsEntry : walsByPrefix.entrySet()) {<a name="line.760"></a>
-<span class="sourceLineNo">761</span>            SortedSet&lt;String&gt; wals = walsEntry.getValue();<a name="line.761"></a>
-<span class="sourceLineNo">762</span>            if (this.sources.isEmpty()) {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>              // If there's no slaves, don't need to keep the old wals since<a name="line.763"></a>
-<span class="sourceLineNo">764</span>              // we only consider the last one when a new slave comes in<a name="line.764"></a>
-<span class="sourceLineNo">765</span>              wals.clear();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>            }<a name="line.766"></a>
-<span class="sourceLineNo">767</span>            if (logPrefix.equals(walsEntry.getKey())) {<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              wals.add(logName);<a name="line.768"></a>
-<span class="sourceLineNo">769</span>              existingPrefix = true;<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            }<a name="line.770"></a>
-<span class="sourceLineNo">771</span>          }<a name="line.771"></a>
-<span class="sourceLineNo">772</span>          if (!existingPrefix) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>            // The new log belongs to a new group, add it into this peer<a name="line.773"></a>
-<span class="sourceLineNo">774</span>            LOG.debug("Start tracking logs for wal group {} for peer {}", logPrefix, peerId);<a name="line.774"></a>
-<span class="sourceLineNo">775</span>            NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.775"></a>
-<span class="sourceLineNo">776</span>            wals.add(logName);<a name="line.776"></a>
-<span class="sourceLineNo">777</span>            walsByPrefix.put(logPrefix, wals);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>          }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>        }<a name="line.779"></a>
-<span class="sourceLineNo">780</span>      }<a name="line.780"></a>
-<span class="sourceLineNo">781</span><a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Add to latestPaths<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      Iterator&lt;Path&gt; iterator = latestPaths.iterator();<a name="line.783"></a>
-<span class="sourceLineNo">784</span>      while (iterator.hasNext()) {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        Path path = iterator.next();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>        if (path.getName().contains(logPrefix)) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>          iterator.remove();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>          break;<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        }<a name="line.789"></a>
-<span class="sourceLineNo">790</span>      }<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      this.latestPaths.add(newLog);<a name="line.791"></a>
+<span class="sourceLineNo">374</span>      if (!latestPaths.isEmpty()) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        for (Map.Entry&lt;String, Path&gt; walPrefixAndPath : latestPaths.entrySet()) {<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          Path walPath = walPrefixAndPath.getValue();<a name="line.376"></a>
+<span class="sourceLineNo">377</span>          NavigableSet&lt;String&gt; wals = new TreeSet&lt;&gt;();<a name="line.377"></a>
+<span class="sourceLineNo">378</span>          wals.add(walPath.getName());<a name="line.378"></a>
+<span class="sourceLineNo">379</span>          walsByGroup.put(walPrefixAndPath.getKey(), wals);<a name="line.379"></a>
+<span class="sourceLineNo">380</span>          // Abort RS and throw exception to make add peer failed<a name="line.380"></a>
+<span class="sourceLineNo">381</span>          abortAndThrowIOExceptionWhenFail(<a name="line.381"></a>
+<span class="sourceLineNo">382</span>            () -&gt; this.queueStorage.addWAL(server.getServerName(), peerId, walPath.getName()));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>          src.enqueueLog(walPath);<a name="line.383"></a>
+<span class="sourceLineNo">384</span>        }<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>    ReplicationPeerConfig peerConfig = peer.getPeerConfig();<a name="line.387"></a>
+<span class="sourceLineNo">388</span>    if (peerConfig.isSyncReplication()) {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>      syncReplicationPeerMappingManager.add(peer.getId(), peerConfig);<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    }<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    src.startup();<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    return src;<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  }<a name="line.393"></a>
+<span class="sourceLineNo">394</span><a name="line.394"></a>
+<span class="sourceLineNo">395</span>  /**<a name="line.395"></a>
+<span class="sourceLineNo">396</span>   * &lt;p&gt;<a name="line.396"></a>
+<span class="sourceLineNo">397</span>   * This is used when we transit a sync replication peer to {@link SyncReplicationState#STANDBY}.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>   * &lt;/p&gt;<a name="line.398"></a>
+<span class="sourceLineNo">399</span>   * &lt;p&gt;<a name="line.399"></a>
+<span class="sourceLineNo">400</span>   * When transiting to {@link SyncReplicationState#STANDBY}, we can remove all the pending wal<a name="line.400"></a>
+<span class="sourceLineNo">401</span>   * files for a replication peer as we do not need to replicate them any more. And this is<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * necessary, otherwise when we transit back to {@link SyncReplicationState#DOWNGRADE_ACTIVE}<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * later, the stale data will be replicated again and cause inconsistency.<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * &lt;/p&gt;<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   * &lt;p&gt;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * See HBASE-20426 for more details.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   * &lt;/p&gt;<a name="line.407"></a>
+<span class="sourceLineNo">408</span>   * @param peerId the id of the sync replication peer<a name="line.408"></a>
+<span class="sourceLineNo">409</span>   */<a name="line.409"></a>
+<span class="sourceLineNo">410</span>  public void drainSources(String peerId) throws IOException, ReplicationException {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    String terminateMessage = "Sync replication peer " + peerId +<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      " is transiting to STANDBY. Will close the previous replication source and open a new one";<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    assert peer.getPeerConfig().isSyncReplication();<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.415"></a>
+<span class="sourceLineNo">416</span>    // synchronized here to avoid race with preLogRoll where we add new log to source and also<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    // walsById.<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    ReplicationSourceInterface toRemove;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    Map&lt;String, NavigableSet&lt;String&gt;&gt; wals = new HashMap&lt;&gt;();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    synchronized (latestPaths) {<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      toRemove = sources.put(peerId, src);<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      if (toRemove != null) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        toRemove.terminate(terminateMessage);<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        toRemove.getSourceMetrics().clear();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      }<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      // Here we make a copy of all the remaining wal files and then delete them from the<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      // replication queue storage after releasing the lock. It is not safe to just remove the old<a name="line.428"></a>
+<span class="sourceLineNo">429</span>      // map from walsById since later we may fail to delete them from the replication queue<a name="line.429"></a>
+<span class="sourceLineNo">430</span>      // storage, and when we retry next time, we can not know the wal files that need to be deleted<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      // from the replication queue storage.<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      walsById.get(peerId).forEach((k, v) -&gt; wals.put(k, new TreeSet&lt;&gt;(v)));<a name="line.432"></a>
+<span class="sourceLineNo">433</span>    }<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    src.startup();<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    for (NavigableSet&lt;String&gt; walsByGroup : wals.values()) {<a name="line.436"></a>
+<span class="sourceLineNo">437</span>      for (String wal : walsByGroup) {<a name="line.437"></a>
+<span class="sourceLineNo">438</span>        queueStorage.removeWAL(server.getServerName(), peerId, wal);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>      }<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    }<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    synchronized (walsById) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      Map&lt;String, NavigableSet&lt;String&gt;&gt; oldWals = walsById.get(peerId);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>      wals.forEach((k, v) -&gt; {<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        NavigableSet&lt;String&gt; walsByGroup = oldWals.get(k);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>        if (walsByGroup != null) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>          walsByGroup.removeAll(v);<a name="line.446"></a>
+<span class="sourceLineNo">447</span>        }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      });<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker. Since NodeFailoverWorker is<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    // a background task, we will delete the file from replication queue storage under the lock to<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    // simplify the logic.<a name="line.452"></a>
+<span class="sourceLineNo">453</span>    synchronized (this.oldsources) {<a name="line.453"></a>
+<span class="sourceLineNo">454</span>      for (Iterator&lt;ReplicationSourceInterface&gt; iter = oldsources.iterator(); iter.hasNext();) {<a name="line.454"></a>
+<span class="sourceLineNo">455</span>        ReplicationSourceInterface oldSource = iter.next();<a name="line.455"></a>
+<span class="sourceLineNo">456</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>          String queueId = oldSource.getQueueId();<a name="line.457"></a>
+<span class="sourceLineNo">458</span>          oldSource.terminate(terminateMessage);<a name="line.458"></a>
+<span class="sourceLineNo">459</span>          oldSource.getSourceMetrics().clear();<a name="line.459"></a>
+<span class="sourceLineNo">460</span>          queueStorage.removeQueue(server.getServerName(), queueId);<a name="line.460"></a>
+<span class="sourceLineNo">461</span>          walsByIdRecoveredQueues.remove(queueId);<a name="line.461"></a>
+<span class="sourceLineNo">462</span>          iter.remove();<a name="line.462"></a>
+<span class="sourceLineNo">463</span>        }<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      }<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
+<span class="sourceLineNo">467</span><a name="line.467"></a>
+<span class="sourceLineNo">468</span>  /**<a name="line.468"></a>
+<span class="sourceLineNo">469</span>   * Close the previous replication sources of this peer id and open new sources to trigger the new<a name="line.469"></a>
+<span class="sourceLineNo">470</span>   * replication state changes or new replication config changes. Here we don't need to change<a name="line.470"></a>
+<span class="sourceLineNo">471</span>   * replication queue storage and only to enqueue all logs to the new replication source<a name="line.471"></a>
+<span class="sourceLineNo">472</span>   * @param peerId the id of the replication peer<a name="line.472"></a>
+<span class="sourceLineNo">473</span>   */<a name="line.473"></a>
+<span class="sourceLineNo">474</span>  public void refreshSources(String peerId) throws IOException {<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    String terminateMessage = "Peer " + peerId +<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      " state or config changed. Will close the previous replication source and open a new one";<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    ReplicationPeer peer = replicationPeers.getPeer(peerId);<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    ReplicationSourceInterface src = createSource(peerId, peer);<a name="line.478"></a>
+<span class="sourceLineNo">479</span>    // synchronized on latestPaths to avoid missing the new log<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    synchronized (this.latestPaths) {<a name="line.480"></a>
+<span class="sourceLineNo">481</span>      ReplicationSourceInterface toRemove = this.sources.put(peerId, src);<a name="line.481"></a>
+<span class="sourceLineNo">482</span>      if (toRemove != null) {<a name="line.482"></a>
+<span class="sourceLineNo">483</span>        LOG.info("Terminate replication source for " + toRemove.getPeerId());<a name="line.483"></a>
+<span class="sourceLineNo">484</span>        toRemove.terminate(terminateMessage);<a name="line.484"></a>
+<span class="sourceLineNo">485</span>      }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>      for (NavigableSet&lt;String&gt; walsByGroup : walsById.get(peerId).values()) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>        walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(this.logDir, wal)));<a name="line.487"></a>
+<span class="sourceLineNo">488</span>      }<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    }<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    LOG.info("Startup replication source for " + src.getPeerId());<a name="line.490"></a>
+<span class="sourceLineNo">491</span>    src.startup();<a name="line.491"></a>
+<span class="sourceLineNo">492</span><a name="line.492"></a>
+<span class="sourceLineNo">493</span>    List&lt;ReplicationSourceInterface&gt; toStartup = new ArrayList&lt;&gt;();<a name="line.493"></a>
+<span class="sourceLineNo">494</span>    // synchronized on oldsources to avoid race with NodeFailoverWorker<a name="line.494"></a>
+<span class="sourceLineNo">495</span>    synchronized (this.oldsources) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>      List&lt;String&gt; previousQueueIds = new ArrayList&lt;&gt;();<a name="line.496"></a>
+<span class="sourceLineNo">497</span>      for (ReplicationSourceInterface oldSource : this.oldsources) {<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        if (oldSource.getPeerId().equals(peerId)) {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          previousQueueIds.add(oldSource.getQueueId());<a name="line.499"></a>
+<span class="sourceLineNo">500</span>          oldSource.terminate(terminateMessage);<a name="line.500"></a>
+<span class="sourceLineNo">501</span>          this.oldsources.remove(oldSource);<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>      for (String queueId : previousQueueIds) {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>        ReplicationSourceInterface replicationSource = createSource(queueId, peer);<a name="line.505"></a>
+<span class="sourceLineNo">506</span>        this.oldsources.add(replicationSource);<a name="line.506"></a>
+<span class="sourceLineNo">507</span>        for (SortedSet&lt;String&gt; walsByGroup : walsByIdRecoveredQueues.get(queueId).values()) {<a name="line.507"></a>
+<span class="sourceLineNo">508</span>          walsByGroup.forEach(wal -&gt; src.enqueueLog(new Path(wal)));<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
+<span class="sourceLineNo">510</span>        toStartup.add(replicationSource);<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      }<a name="line.511"></a>
+<span class="sourceLineNo">512</span>    }<a name="line.512"></a>
+<span class="sourceLineNo">513</span>    for (ReplicationSourceInterface replicationSource : toStartup) {<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      replicationSource.startup();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>    }<a name="line.515"></a>
+<span class="sourceLineNo">516</span>  }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>  /**<a name="line.518"></a>
+<span class="sourceLineNo">519</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.519"></a>
+<span class="sourceLineNo">520</span>   * @param src source to clear<a name="line.520"></a>
+<span class="sourceLineNo">521</span>   */<a name="line.521"></a>
+<span class="sourceLineNo">522</span>  private boolean removeRecoveredSource(ReplicationSourceInterface src) {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    if (!this.oldsources.remove(src)) {<a name="line.523"></a>
+<span class="sourceLineNo">524</span>      return false;<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    LOG.info("Done with the recovered queue {}", src.getQueueId());<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    // Delete queue from storage and memory<a name="line.527"></a>
+<span class="sourceLineNo">528</span>    deleteQueue(src.getQueueId());<a name="line.528"></a>
+<span class="sourceLineNo">529</span>    this.walsByIdRecoveredQueues.remove(src.getQueueId());<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    return true;<a name="line.530"></a>
+<span class="sourceLineNo">531</span>  }<a name="line.531"></a>
+<span class="sourceLineNo">532</span><a name="line.532"></a>
+<span class="sourceLineNo">533</span>  void finishRecoveredSource(ReplicationSourceInterface src) {<a name="line.533"></a>
+<span class="sourceLineNo">534</span>    synchronized (oldsources) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>      if (!removeRecoveredSource(src)) {<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        return;<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>    LOG.info("Finished recovering queue {} with the following stats: {}", src.getQueueId(),<a name="line.539"></a>
+<span class="sourceLineNo">540</span>      src.getStats());<a name="line.540"></a>
+<span class="sourceLineNo">541</span>  }<a name="line.541"></a>
+<span class="sourceLineNo">542</span><a name="line.542"></a>
+<span class="sourceLineNo">543</span>  /**<a name="line.543"></a>
+<span class="sourceLineNo">544</span>   * Clear the metrics and related replication queue of the specified old source<a name="line.544"></a>
+<span class="sourceLineNo">545</span>   * @param src source to clear<a name="line.545"></a>
+<span class="sourceLineNo">546</span>   */<a name="line.546"></a>
+<span class="sourceLineNo">547</span>  void removeSource(ReplicationSourceInterface src) {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    LOG.info("Done with the queue " + src.getQueueId());<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    this.sources.remove(src.getPeerId());<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    // Delete queue from storage and memory<a name="line.550"></a>
+<span class="sourceLineNo">551</span>    deleteQueue(src.getQueueId());<a name="line.551"></a>
+<span class="sourceLineNo">552</span>    this.walsById.remove(src.getQueueId());<a name="line.552"></a>
+<span class="sourceLineNo">553</span><a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
+<span class="sourceLineNo">557</span>   * Delete a complete queue of wals associated with a replication source<a name="line.557"></a>
+<span class="sourceLineNo">558</span>   * @param queueId the id of replication queue to delete<a name="line.558"></a>
+<span class="sourceLineNo">559</span>   */<a name="line.559"></a>
+<span class="sourceLineNo">560</span>  private void deleteQueue(String queueId) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    abortWhenFail(() -&gt; this.queueStorage.removeQueue(server.getServerName(), queueId));<a name="line.561"></a>
+<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
+<span class="sourceLineNo">563</span><a name="line.563"></a>
+<span class="sourceLineNo">564</span>  @FunctionalInterface<a name="line.564"></a>
+<span class="sourceLineNo">565</span>  private interface ReplicationQueueOperation {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    void exec() throws ReplicationException;<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>   * Refresh replication source will terminate the old source first, then the source thread will be<a name="line.570"></a>
+<span class="sourceLineNo">571</span>   * interrupted. Need to handle it instead of abort the region server.<a name="line.571"></a>
+<span class="sourceLineNo">572</span>   */<a name="line.572"></a>
+<span class="sourceLineNo">573</span>  private void interruptOrAbortWhenFail(ReplicationQueueOperation op) {<a name="line.573"></a>
+<span class="sourceLineNo">574</span>    try {<a name="line.574"></a>
+<span class="sourceLineNo">575</span>      op.exec();<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    } catch (ReplicationException e) {<a name="line.576"></a>
+<span class="sourceLineNo">577</span>      if (e.getCause() != null &amp;&amp; e.getCause() instanceof KeeperException.SystemErrorException<a name="line.577"></a>
+<span class="sourceLineNo">578</span>          &amp;&amp; e.getCause().getCause() != null &amp;&amp; e.getCause()<a name="line.578"></a>
+<span class="sourceLineNo">579</span>          .getCause() instanceof InterruptedException) {<a name="line.579"></a>
+<span class="sourceLineNo">580</span>        throw new RuntimeException(<a name="line.580"></a>
+<span class="sourceLineNo">581</span>            "Thread is interrupted, the replication source may be terminated");<a name="line.581"></a>
+<span class="sourceLineNo">582</span>      }<a name="line.582"></a>
+<span class="sourceLineNo">583</span>      server.abort("Failed to operate on replication queue", e);<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    }<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  private void abortWhenFail(ReplicationQueueOperation op) {<a name="line.587"></a>
+<span class="sourceLineNo">588</span>    try {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>      op.exec();<a name="line.589"></a>
+<span class="sourceLineNo">590</span>    } catch (ReplicationException e) {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>      server.abort("Failed to operate on replication queue", e);<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><a name="line.594"></a>
+<span class="sourceLineNo">595</span>  private void throwIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>    try {<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      op.exec();<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    } catch (ReplicationException e) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      throw new IOException(e);<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>  private void abortAndThrowIOExceptionWhenFail(ReplicationQueueOperation op) throws IOException {<a name="line.603"></a>
+<span class="sourceLineNo">604</span>    try {<a name="line.604"></a>
+<span class="sourceLineNo">605</span>      op.exec();<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    } catch (ReplicationException e) {<a name="line.606"></a>
+<span class="sourceLineNo">607</span>      server.abort("Failed to operate on replication queue", e);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      throw new IOException(e);<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>  /**<a name="line.612"></a>
+<span class="sourceLineNo">613</span>   * This method will log the current position to storage. And also clean old logs from the<a name="line.613"></a>
+<span class="sourceLineNo">614</span>   * replication queue.<a name="line.614"></a>
+<span class="sourceLineNo">615</span>   * @param source the replication source<a name="line.615"></a>
+<span class="sourceLineNo">616</span>   * @param entryBatch the wal entry batch we just shipped<a name="line.616"></a>
+<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
+<span class="sourceLineNo">618</span>  public void logPositionAndCleanOldLogs(ReplicationSourceInterface source,<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      WALEntryBatch entryBatch) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>    String fileName = entryBatch.getLastWalPath().getName();<a name="line.620"></a>
+<span class="sourceLineNo">621</span>    interruptOrAbortWhenFail(() -&gt; this.queueStorage.setWALPosition(server.getServerName(),<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      source.getQueueId(), fileName, entryBatch.getLastWalPosition(), entryBatch.getLastSeqIds()));<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    cleanOldLogs(fileName, entryBatch.isEndOfFile(), source);<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>  /**<a name="line.626"></a>
+<span class="sourceLineNo">627</span>   * Cleans a log file and all older logs from replication queue. Called when we are sure that a log<a name="line.627"></a>
+<span class="sourceLineNo">628</span>   * file is closed and has no more entries.<a name="line.628"></a>
+<span class="sourceLineNo">629</span>   * @param log Path to the log<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * @param inclusive whether we should also remove the given log file<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * @param source the replication source<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   */<a name="line.632"></a>
+<span class="sourceLineNo">633</span>  @VisibleForTesting<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  void cleanOldLogs(String log, boolean inclusive, ReplicationSourceInterface source) {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    String logPrefix = AbstractFSWALProvider.getWALPrefixFromWALName(log);<a name="line.635"></a>
+<span class="sourceLineNo">636</span>    if (source.isRecovered()) {<a name="line.636"></a>
+<span class="sourceLineNo">637</span>      NavigableSet&lt;String&gt; wals = walsByIdRecoveredQueues.get(source.getQueueId()).get(logPrefix);<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      if (wals != null) {<a name="line.638"></a>
+<span class="sourceLineNo">639</span>        NavigableSet&lt;String&gt; walsToRemove = wals.headSet(log, inclusive);<a name="line.639"></a>
+<span class="sourceLineNo">640</span>        if (walsToRemove.isEmpty()) {<a name="line.640"></a>
+<span class="sourceLineNo">641</span>          return;<a name="line.641"></a>
+<span class="sourceLineNo">642</span>        }<a name="line.642"></a>
+<span class="sourceLineNo">643</span>        cleanOldLogs(walsToRemove, source);<a name="line.643"></a>
+<span class="sourceLineNo">644</span>        walsToRemove.clear();<a name="line.644"></a>
+<span class="sourceLineNo">645</span>      }<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    } else {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      NavigableSet&lt;String&gt; wals;<a name="line.647"></a>
+<span class="sourceLineNo">648</span>      NavigableSet&lt;String&gt; walsToRemove;<a name="line.648"></a>
+<span class="sourceLineNo">649</span>      // synchronized on walsById to avoid race with preLogRoll<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      synchronized (this.walsById) {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>        wals = walsById.get(source.getQueueId()).get(logPrefix);<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        if (wals == null) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>          return;<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        }<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        walsToRemove = wals.headSet(log, inclusive);<a name="line.655"></a>
+<span class="sourceLineNo">656</span>        if (walsToRemove.isEmpty()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>          return;<a name="line.657"></a>
+<span class="sourceLineNo">658</span>        }<a name="line.658"></a>
+<span class="sourceLineNo">659</span>        walsToRemove = new TreeSet&lt;&gt;(walsToRemove);<a name="line.659"></a>
+<span class="sourceLineNo">660</span>      }<a name="line.660"></a>
+<span class="sourceLineNo">661</span>      // cleanOldLogs may spend some time, especially for sync replication where we may want to<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      // remove remote wals as the remote cluster may have already been down, so we do it outside<a name="line.662"></a>
+<span class="sourceLineNo">663</span>      // the lock to avoid block preLogRoll<a name="line.663"></a>
+<span class="sourceLineNo">664</span>      cleanOldLogs(walsToRemove, source);<a name="line.664"></a>
+<span class="sourceLineNo">665</span>      // now let's remove the files in the set<a name="line.665"></a>
+<span class="sourceLineNo">666</span>      synchronized (this.walsById) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>        wals.removeAll(walsToRemove);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>      }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>    }<a name="line.669"></a>
+<span class="sourceLineNo">670</span>  }<a name="line.670"></a>
+<span class="sourceLineNo">671</span><a name="line.671"></a>
+<span class="sourceLineNo">672</span>  private void removeRemoteWALs(String peerId, String remoteWALDir, Collection&lt;String&gt; wals)<a name="line.672"></a>
+<span class="sourceLineNo">673</span>      throws IOException {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>    Path remoteWALDirForPeer = ReplicationUtils.getPeerRemoteWALDir(remoteWALDir, peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    FileSystem fs = ReplicationUtils.getRemoteWALFileSystem(conf, remoteWALDir);<a name="line.675"></a>
+<span class="sourceLineNo">676</span>    for (String wal : wals) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      Path walFile = new Path(remoteWALDirForPeer, wal);<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      try {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        if (!fs.delete(walFile, false) &amp;&amp; fs.exists(walFile)) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          throw new IOException("Can not delete " + walFile);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>        }<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      } catch (FileNotFoundException e) {<a name="line.682"></a>
+<span class="sourceLineNo">683</span>        // Just ignore since this means the file has already been deleted.<a name="line.683"></a>
+<span class="sourceLineNo">684</span>        // The javadoc of the FileSystem.delete methods does not specify the behavior of deleting an<a name="line.684"></a>
+<span class="sourceLineNo">685</span>        // inexistent file, so here we deal with both, i.e, check the return value of the<a name="line.685"></a>
+<span class="sourceLineNo">686</span>        // FileSystem.delete, and also catch FNFE.<a name="line.686"></a>
+<span class="sourceLineNo">687</span>        LOG.debug("The remote wal {} has already been deleted?", walFile, e);<a name="line.687"></a>
+<span class="sourceLineNo">688</span>      }<a name="line.688"></a>
+<span class="sourceLineNo">6

<TRUNCATED>

[38/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
index 6df10fd..96d95ad 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/client/RegionInfo.html
@@ -26,742 +26,764 @@
 <span class="sourceLineNo">018</span> */<a name="line.18"></a>
 <span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.client;<a name="line.19"></a>
 <span class="sourceLineNo">020</span><a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.DataInputStream;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import java.io.IOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.ArrayList;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.Arrays;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import java.util.Comparator;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import java.util.List;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import java.util.stream.Collectors;<a name="line.27"></a>
-<span class="sourceLineNo">028</span><a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.HConstants;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.TableName;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.exceptions.DeserializationException;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.util.ByteArrayHashKey;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.util.HashKey;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.util.JenkinsHash;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.MD5Hash;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.io.DataInputBuffer;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.hadoop.util.StringUtils;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.39"></a>
-<span class="sourceLineNo">040</span><a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;<a name="line.42"></a>
-<span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>/**<a name="line.44"></a>
-<span class="sourceLineNo">045</span> * Information about a region. A region is a range of keys in the whole keyspace<a name="line.45"></a>
-<span class="sourceLineNo">046</span> * of a table, an identifier (a timestamp) for differentiating between subset<a name="line.46"></a>
-<span class="sourceLineNo">047</span> * ranges (after region split) and a replicaId for differentiating the instance<a name="line.47"></a>
-<span class="sourceLineNo">048</span> * for the same range and some status information about the region.<a name="line.48"></a>
-<span class="sourceLineNo">049</span> *<a name="line.49"></a>
-<span class="sourceLineNo">050</span> * The region has a unique name which consists of the following fields:<a name="line.50"></a>
-<span class="sourceLineNo">051</span> * &lt;ul&gt;<a name="line.51"></a>
-<span class="sourceLineNo">052</span> * &lt;li&gt; tableName   : The name of the table &lt;/li&gt;<a name="line.52"></a>
-<span class="sourceLineNo">053</span> * &lt;li&gt; startKey    : The startKey for the region. &lt;/li&gt;<a name="line.53"></a>
-<span class="sourceLineNo">054</span> * &lt;li&gt; regionId    : A timestamp when the region is created. &lt;/li&gt;<a name="line.54"></a>
-<span class="sourceLineNo">055</span> * &lt;li&gt; replicaId   : An id starting from 0 to differentiate replicas of the<a name="line.55"></a>
-<span class="sourceLineNo">056</span> * same region range but hosted in separated servers. The same region range can<a name="line.56"></a>
-<span class="sourceLineNo">057</span> * be hosted in multiple locations.&lt;/li&gt;<a name="line.57"></a>
-<span class="sourceLineNo">058</span> * &lt;li&gt; encodedName : An MD5 encoded string for the region name.&lt;/li&gt;<a name="line.58"></a>
-<span class="sourceLineNo">059</span> * &lt;/ul&gt;<a name="line.59"></a>
-<span class="sourceLineNo">060</span> *<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * &lt;br&gt; Other than the fields in the region name, region info contains:<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;li&gt; endKey      : the endKey for the region (exclusive) &lt;/li&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt; split       : Whether the region is split &lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt; offline     : Whether the region is offline &lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;/ul&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> *<a name="line.67"></a>
-<span class="sourceLineNo">068</span> */<a name="line.68"></a>
-<span class="sourceLineNo">069</span>@InterfaceAudience.Public<a name="line.69"></a>
-<span class="sourceLineNo">070</span>public interface RegionInfo {<a name="line.70"></a>
-<span class="sourceLineNo">071</span>  /**<a name="line.71"></a>
-<span class="sourceLineNo">072</span>   * Separator used to demarcate the encodedName in a region name<a name="line.72"></a>
-<span class="sourceLineNo">073</span>   * in the new format. See description on new format above.<a name="line.73"></a>
-<span class="sourceLineNo">074</span>   */<a name="line.74"></a>
-<span class="sourceLineNo">075</span>  @InterfaceAudience.Private<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  int ENC_SEPARATOR = '.';<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  @InterfaceAudience.Private<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  int MD5_HEX_LENGTH = 32;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  @InterfaceAudience.Private<a name="line.81"></a>
-<span class="sourceLineNo">082</span>  int DEFAULT_REPLICA_ID = 0;<a name="line.82"></a>
-<span class="sourceLineNo">083</span><a name="line.83"></a>
-<span class="sourceLineNo">084</span>  /**<a name="line.84"></a>
-<span class="sourceLineNo">085</span>   * to keep appended int's sorted in string format. Only allows 2 bytes<a name="line.85"></a>
-<span class="sourceLineNo">086</span>   * to be sorted for replicaId.<a name="line.86"></a>
-<span class="sourceLineNo">087</span>   */<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  @InterfaceAudience.Private<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  String REPLICA_ID_FORMAT = "%04X";<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>  @InterfaceAudience.Private<a name="line.91"></a>
-<span class="sourceLineNo">092</span>  byte REPLICA_ID_DELIMITER = (byte)'_';<a name="line.92"></a>
-<span class="sourceLineNo">093</span><a name="line.93"></a>
-<span class="sourceLineNo">094</span>  @InterfaceAudience.Private<a name="line.94"></a>
-<span class="sourceLineNo">095</span>  String INVALID_REGION_NAME_FORMAT_MESSAGE = "Invalid regionName format";<a name="line.95"></a>
-<span class="sourceLineNo">096</span><a name="line.96"></a>
-<span class="sourceLineNo">097</span>  @InterfaceAudience.Private<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  Comparator&lt;RegionInfo&gt; COMPARATOR<a name="line.98"></a>
-<span class="sourceLineNo">099</span>    = (RegionInfo lhs, RegionInfo rhs) -&gt; {<a name="line.99"></a>
-<span class="sourceLineNo">100</span>      if (rhs == null) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>        return 1;<a name="line.101"></a>
-<span class="sourceLineNo">102</span>      }<a name="line.102"></a>
-<span class="sourceLineNo">103</span><a name="line.103"></a>
-<span class="sourceLineNo">104</span>      // Are regions of same table?<a name="line.104"></a>
-<span class="sourceLineNo">105</span>      int result = lhs.getTable().compareTo(rhs.getTable());<a name="line.105"></a>
-<span class="sourceLineNo">106</span>      if (result != 0) {<a name="line.106"></a>
-<span class="sourceLineNo">107</span>        return result;<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      }<a name="line.108"></a>
-<span class="sourceLineNo">109</span><a name="line.109"></a>
-<span class="sourceLineNo">110</span>      // Compare start keys.<a name="line.110"></a>
-<span class="sourceLineNo">111</span>      result = Bytes.compareTo(lhs.getStartKey(), rhs.getStartKey());<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      if (result != 0) {<a name="line.112"></a>
-<span class="sourceLineNo">113</span>        return result;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      }<a name="line.114"></a>
-<span class="sourceLineNo">115</span><a name="line.115"></a>
-<span class="sourceLineNo">116</span>      // Compare end keys.<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      result = Bytes.compareTo(lhs.getEndKey(), rhs.getEndKey());<a name="line.117"></a>
-<span class="sourceLineNo">118</span><a name="line.118"></a>
-<span class="sourceLineNo">119</span>      if (result != 0) {<a name="line.119"></a>
-<span class="sourceLineNo">120</span>        if (lhs.getStartKey().length != 0<a name="line.120"></a>
-<span class="sourceLineNo">121</span>                &amp;&amp; lhs.getEndKey().length == 0) {<a name="line.121"></a>
-<span class="sourceLineNo">122</span>            return 1; // this is last region<a name="line.122"></a>
-<span class="sourceLineNo">123</span>        }<a name="line.123"></a>
-<span class="sourceLineNo">124</span>        if (rhs.getStartKey().length != 0<a name="line.124"></a>
-<span class="sourceLineNo">125</span>                &amp;&amp; rhs.getEndKey().length == 0) {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>            return -1; // o is the last region<a name="line.126"></a>
-<span class="sourceLineNo">127</span>        }<a name="line.127"></a>
-<span class="sourceLineNo">128</span>        return result;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      }<a name="line.129"></a>
-<span class="sourceLineNo">130</span><a name="line.130"></a>
-<span class="sourceLineNo">131</span>      // regionId is usually milli timestamp -- this defines older stamps<a name="line.131"></a>
-<span class="sourceLineNo">132</span>      // to be "smaller" than newer stamps in sort order.<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      if (lhs.getRegionId() &gt; rhs.getRegionId()) {<a name="line.133"></a>
-<span class="sourceLineNo">134</span>        return 1;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      } else if (lhs.getRegionId() &lt; rhs.getRegionId()) {<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        return -1;<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      }<a name="line.137"></a>
-<span class="sourceLineNo">138</span><a name="line.138"></a>
-<span class="sourceLineNo">139</span>      int replicaDiff = lhs.getReplicaId() - rhs.getReplicaId();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>      if (replicaDiff != 0) return replicaDiff;<a name="line.140"></a>
-<span class="sourceLineNo">141</span><a name="line.141"></a>
-<span class="sourceLineNo">142</span>      if (lhs.isOffline() == rhs.isOffline())<a name="line.142"></a>
-<span class="sourceLineNo">143</span>        return 0;<a name="line.143"></a>
-<span class="sourceLineNo">144</span>      if (lhs.isOffline() == true) return -1;<a name="line.144"></a>
-<span class="sourceLineNo">145</span><a name="line.145"></a>
-<span class="sourceLineNo">146</span>      return 1;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  };<a name="line.147"></a>
-<span class="sourceLineNo">148</span><a name="line.148"></a>
-<span class="sourceLineNo">149</span><a name="line.149"></a>
-<span class="sourceLineNo">150</span>  /**<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * @return Return a short, printable name for this region<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * (usually encoded name) for us logging.<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   */<a name="line.153"></a>
-<span class="sourceLineNo">154</span>  String getShortNameToLog();<a name="line.154"></a>
-<span class="sourceLineNo">155</span><a name="line.155"></a>
-<span class="sourceLineNo">156</span>  /**<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * @return the regionId.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  long getRegionId();<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  /**<a name="line.161"></a>
-<span class="sourceLineNo">162</span>   * @return the regionName as an array of bytes.<a name="line.162"></a>
-<span class="sourceLineNo">163</span>   * @see #getRegionNameAsString()<a name="line.163"></a>
-<span class="sourceLineNo">164</span>   */<a name="line.164"></a>
-<span class="sourceLineNo">165</span>  byte [] getRegionName();<a name="line.165"></a>
-<span class="sourceLineNo">166</span><a name="line.166"></a>
-<span class="sourceLineNo">167</span>  /**<a name="line.167"></a>
-<span class="sourceLineNo">168</span>   * @return Region name as a String for use in logging, etc.<a name="line.168"></a>
-<span class="sourceLineNo">169</span>   */<a name="line.169"></a>
-<span class="sourceLineNo">170</span>  String getRegionNameAsString();<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>  /**<a name="line.172"></a>
-<span class="sourceLineNo">173</span>   * @return the encoded region name.<a name="line.173"></a>
-<span class="sourceLineNo">174</span>   */<a name="line.174"></a>
-<span class="sourceLineNo">175</span>  String getEncodedName();<a name="line.175"></a>
-<span class="sourceLineNo">176</span><a name="line.176"></a>
-<span class="sourceLineNo">177</span>  /**<a name="line.177"></a>
-<span class="sourceLineNo">178</span>   * @return the encoded region name as an array of bytes.<a name="line.178"></a>
-<span class="sourceLineNo">179</span>   */<a name="line.179"></a>
-<span class="sourceLineNo">180</span>  byte [] getEncodedNameAsBytes();<a name="line.180"></a>
-<span class="sourceLineNo">181</span><a name="line.181"></a>
-<span class="sourceLineNo">182</span>  /**<a name="line.182"></a>
-<span class="sourceLineNo">183</span>   * @return the startKey.<a name="line.183"></a>
-<span class="sourceLineNo">184</span>   */<a name="line.184"></a>
-<span class="sourceLineNo">185</span>  byte [] getStartKey();<a name="line.185"></a>
-<span class="sourceLineNo">186</span><a name="line.186"></a>
-<span class="sourceLineNo">187</span>  /**<a name="line.187"></a>
-<span class="sourceLineNo">188</span>   * @return the endKey.<a name="line.188"></a>
-<span class="sourceLineNo">189</span>   */<a name="line.189"></a>
-<span class="sourceLineNo">190</span>  byte [] getEndKey();<a name="line.190"></a>
-<span class="sourceLineNo">191</span><a name="line.191"></a>
-<span class="sourceLineNo">192</span>  /**<a name="line.192"></a>
-<span class="sourceLineNo">193</span>   * @return current table name of the region<a name="line.193"></a>
-<span class="sourceLineNo">194</span>   */<a name="line.194"></a>
-<span class="sourceLineNo">195</span>  TableName getTable();<a name="line.195"></a>
-<span class="sourceLineNo">196</span><a name="line.196"></a>
-<span class="sourceLineNo">197</span>  /**<a name="line.197"></a>
-<span class="sourceLineNo">198</span>   * @return returns region replica id<a name="line.198"></a>
-<span class="sourceLineNo">199</span>   */<a name="line.199"></a>
-<span class="sourceLineNo">200</span>  int getReplicaId();<a name="line.200"></a>
-<span class="sourceLineNo">201</span><a name="line.201"></a>
-<span class="sourceLineNo">202</span>  /**<a name="line.202"></a>
-<span class="sourceLineNo">203</span>   * @return True if has been split and has daughters.<a name="line.203"></a>
-<span class="sourceLineNo">204</span>   */<a name="line.204"></a>
-<span class="sourceLineNo">205</span>  boolean isSplit();<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>  /**<a name="line.207"></a>
-<span class="sourceLineNo">208</span>   * @return True if this region is offline.<a name="line.208"></a>
-<span class="sourceLineNo">209</span>   */<a name="line.209"></a>
-<span class="sourceLineNo">210</span>  boolean isOffline();<a name="line.210"></a>
-<span class="sourceLineNo">211</span><a name="line.211"></a>
-<span class="sourceLineNo">212</span>  /**<a name="line.212"></a>
-<span class="sourceLineNo">213</span>   * @return True if this is a split parent region.<a name="line.213"></a>
-<span class="sourceLineNo">214</span>   */<a name="line.214"></a>
-<span class="sourceLineNo">215</span>  boolean isSplitParent();<a name="line.215"></a>
-<span class="sourceLineNo">216</span><a name="line.216"></a>
-<span class="sourceLineNo">217</span>  /**<a name="line.217"></a>
-<span class="sourceLineNo">218</span>   * @return true if this region is a meta region.<a name="line.218"></a>
-<span class="sourceLineNo">219</span>   */<a name="line.219"></a>
-<span class="sourceLineNo">220</span>  boolean isMetaRegion();<a name="line.220"></a>
-<span class="sourceLineNo">221</span><a name="line.221"></a>
-<span class="sourceLineNo">222</span>  /**<a name="line.222"></a>
-<span class="sourceLineNo">223</span>   * @param rangeStartKey<a name="line.223"></a>
-<span class="sourceLineNo">224</span>   * @param rangeEndKey<a name="line.224"></a>
-<span class="sourceLineNo">225</span>   * @return true if the given inclusive range of rows is fully contained<a name="line.225"></a>
-<span class="sourceLineNo">226</span>   * by this region. For example, if the region is foo,a,g and this is<a name="line.226"></a>
-<span class="sourceLineNo">227</span>   * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.227"></a>
-<span class="sourceLineNo">228</span>   * ["b","z"] it will return false.<a name="line.228"></a>
-<span class="sourceLineNo">229</span>   * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.229"></a>
-<span class="sourceLineNo">230</span>   */<a name="line.230"></a>
-<span class="sourceLineNo">231</span>  boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey);<a name="line.231"></a>
-<span class="sourceLineNo">232</span><a name="line.232"></a>
-<span class="sourceLineNo">233</span>  /**<a name="line.233"></a>
-<span class="sourceLineNo">234</span>   * @param row<a name="line.234"></a>
-<span class="sourceLineNo">235</span>   * @return true if the given row falls in this region.<a name="line.235"></a>
-<span class="sourceLineNo">236</span>   */<a name="line.236"></a>
-<span class="sourceLineNo">237</span>  boolean containsRow(byte[] row);<a name="line.237"></a>
-<span class="sourceLineNo">238</span><a name="line.238"></a>
-<span class="sourceLineNo">239</span>  /**<a name="line.239"></a>
-<span class="sourceLineNo">240</span>   * Does region name contain its encoded name?<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * @param regionName region name<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * @return boolean indicating if this a new format region<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   *         name which contains its encoded name.<a name="line.243"></a>
-<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
-<span class="sourceLineNo">245</span>  @InterfaceAudience.Private<a name="line.245"></a>
-<span class="sourceLineNo">246</span>  static boolean hasEncodedName(final byte[] regionName) {<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    // check if region name ends in ENC_SEPARATOR<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    return (regionName.length &gt;= 1) &amp;&amp;<a name="line.248"></a>
-<span class="sourceLineNo">249</span>      (regionName[regionName.length - 1] == RegionInfo.ENC_SEPARATOR);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>  }<a name="line.250"></a>
-<span class="sourceLineNo">251</span><a name="line.251"></a>
-<span class="sourceLineNo">252</span>  /**<a name="line.252"></a>
-<span class="sourceLineNo">253</span>   * @return the encodedName<a name="line.253"></a>
-<span class="sourceLineNo">254</span>   */<a name="line.254"></a>
-<span class="sourceLineNo">255</span>  @InterfaceAudience.Private<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  static String encodeRegionName(final byte [] regionName) {<a name="line.256"></a>
-<span class="sourceLineNo">257</span>    String encodedName;<a name="line.257"></a>
-<span class="sourceLineNo">258</span>    if (hasEncodedName(regionName)) {<a name="line.258"></a>
-<span class="sourceLineNo">259</span>      // region is in new format:<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      // &lt;tableName&gt;,&lt;startKey&gt;,&lt;regionIdTimeStamp&gt;/encodedName/<a name="line.260"></a>
-<span class="sourceLineNo">261</span>      encodedName = Bytes.toString(regionName,<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      regionName.length - MD5_HEX_LENGTH - 1,<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      MD5_HEX_LENGTH);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>    } else {<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      // old format region name. First hbase:meta region also<a name="line.265"></a>
-<span class="sourceLineNo">266</span>      // use this format.EncodedName is the JenkinsHash value.<a name="line.266"></a>
-<span class="sourceLineNo">267</span>      HashKey&lt;byte[]&gt; key = new ByteArrayHashKey(regionName, 0, regionName.length);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>      int hashVal = Math.abs(JenkinsHash.getInstance().hash(key, 0));<a name="line.268"></a>
-<span class="sourceLineNo">269</span>      encodedName = String.valueOf(hashVal);<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    return encodedName;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>  /**<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * (usually encoded name) for us logging.<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   */<a name="line.277"></a>
-<span class="sourceLineNo">278</span>  static String getShortNameToLog(RegionInfo...hris) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>    return getShortNameToLog(Arrays.asList(hris));<a name="line.279"></a>
-<span class="sourceLineNo">280</span>  }<a name="line.280"></a>
-<span class="sourceLineNo">281</span><a name="line.281"></a>
-<span class="sourceLineNo">282</span>  /**<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * (usually encoded name) for us logging.<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   */<a name="line.285"></a>
-<span class="sourceLineNo">286</span>  static String getShortNameToLog(final List&lt;RegionInfo&gt; ris) {<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    return ris.stream().map(ri -&gt; ri.getShortNameToLog()).<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    collect(Collectors.toList()).toString();<a name="line.288"></a>
-<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
-<span class="sourceLineNo">290</span><a name="line.290"></a>
-<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Gets the table name from the specified region name.<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * @param regionName to extract the table name from<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   * @return Table name<a name="line.294"></a>
-<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
-<span class="sourceLineNo">296</span>  @InterfaceAudience.Private<a name="line.296"></a>
-<span class="sourceLineNo">297</span>  // This method should never be used. Its awful doing parse from bytes.<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  // It is fallback in case we can't get the tablename any other way. Could try removing it.<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  // Keeping it Audience Private so can remove at later date.<a name="line.299"></a>
-<span class="sourceLineNo">300</span>  static TableName getTable(final byte [] regionName) {<a name="line.300"></a>
-<span class="sourceLineNo">301</span>    int offset = -1;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    for (int i = 0; i &lt; regionName.length; i++) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      if (regionName[i] == HConstants.DELIMITER) {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>        offset = i;<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        break;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    }<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    if (offset &lt;= 0) {<a name="line.308"></a>
-<span class="sourceLineNo">309</span>      throw new IllegalArgumentException("offset=" + offset);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    byte[] buff  = new byte[offset];<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    System.arraycopy(regionName, 0, buff, 0, offset);<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return TableName.valueOf(buff);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  /**<a name="line.316"></a>
-<span class="sourceLineNo">317</span>   * Gets the start key from the specified region name.<a name="line.317"></a>
-<span class="sourceLineNo">318</span>   * @param regionName<a name="line.318"></a>
-<span class="sourceLineNo">319</span>   * @return Start key.<a name="line.319"></a>
-<span class="sourceLineNo">320</span>   * @throws java.io.IOException<a name="line.320"></a>
-<span class="sourceLineNo">321</span>   */<a name="line.321"></a>
-<span class="sourceLineNo">322</span>  static byte[] getStartKey(final byte[] regionName) throws IOException {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    return parseRegionName(regionName)[1];<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>  @InterfaceAudience.Private<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  static boolean isEncodedRegionName(byte[] regionName) throws IOException {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    try {<a name="line.328"></a>
-<span class="sourceLineNo">329</span>      parseRegionName(regionName);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      return false;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    } catch (IOException e) {<a name="line.331"></a>
-<span class="sourceLineNo">332</span>      if (StringUtils.stringifyException(e)<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      .contains(INVALID_REGION_NAME_FORMAT_MESSAGE)) {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>        return true;<a name="line.334"></a>
-<span class="sourceLineNo">335</span>      }<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      throw e;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    }<a name="line.337"></a>
-<span class="sourceLineNo">338</span>  }<a name="line.338"></a>
-<span class="sourceLineNo">339</span><a name="line.339"></a>
-<span class="sourceLineNo">340</span>  /**<a name="line.340"></a>
-<span class="sourceLineNo">341</span>   * @param bytes<a name="line.341"></a>
-<span class="sourceLineNo">342</span>   * @return A deserialized {@link RegionInfo}<a name="line.342"></a>
-<span class="sourceLineNo">343</span>   * or null if we failed deserialize or passed bytes null<a name="line.343"></a>
-<span class="sourceLineNo">344</span>   */<a name="line.344"></a>
-<span class="sourceLineNo">345</span>  @InterfaceAudience.Private<a name="line.345"></a>
-<span class="sourceLineNo">346</span>  static RegionInfo parseFromOrNull(final byte [] bytes) {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    if (bytes == null) return null;<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    return parseFromOrNull(bytes, 0, bytes.length);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>  }<a name="line.349"></a>
-<span class="sourceLineNo">350</span><a name="line.350"></a>
-<span class="sourceLineNo">351</span>  /**<a name="line.351"></a>
-<span class="sourceLineNo">352</span>   * @param bytes<a name="line.352"></a>
-<span class="sourceLineNo">353</span>   * @param offset<a name="line.353"></a>
-<span class="sourceLineNo">354</span>   * @param len<a name="line.354"></a>
-<span class="sourceLineNo">355</span>   * @return A deserialized {@link RegionInfo} or null<a name="line.355"></a>
-<span class="sourceLineNo">356</span>   *  if we failed deserialize or passed bytes null<a name="line.356"></a>
-<span class="sourceLineNo">357</span>   */<a name="line.357"></a>
-<span class="sourceLineNo">358</span>  @InterfaceAudience.Private<a name="line.358"></a>
-<span class="sourceLineNo">359</span>  static RegionInfo parseFromOrNull(final byte [] bytes, int offset, int len) {<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    if (bytes == null || len &lt;= 0) return null;<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    try {<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      return parseFrom(bytes, offset, len);<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    } catch (DeserializationException e) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      return null;<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><a name="line.367"></a>
-<span class="sourceLineNo">368</span>  /**<a name="line.368"></a>
-<span class="sourceLineNo">369</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.369"></a>
-<span class="sourceLineNo">370</span>   * @return A deserialized {@link RegionInfo}<a name="line.370"></a>
-<span class="sourceLineNo">371</span>   * @throws DeserializationException<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   */<a name="line.372"></a>
-<span class="sourceLineNo">373</span>  @InterfaceAudience.Private<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  static RegionInfo parseFrom(final byte [] bytes) throws DeserializationException {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>    if (bytes == null) return null;<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    return parseFrom(bytes, 0, bytes.length);<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  }<a name="line.377"></a>
-<span class="sourceLineNo">378</span><a name="line.378"></a>
-<span class="sourceLineNo">379</span>  /**<a name="line.379"></a>
-<span class="sourceLineNo">380</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.380"></a>
-<span class="sourceLineNo">381</span>   * @param offset starting point in the byte array<a name="line.381"></a>
-<span class="sourceLineNo">382</span>   * @param len length to read on the byte array<a name="line.382"></a>
-<span class="sourceLineNo">383</span>   * @return A deserialized {@link RegionInfo}<a name="line.383"></a>
-<span class="sourceLineNo">384</span>   * @throws DeserializationException<a name="line.384"></a>
-<span class="sourceLineNo">385</span>   */<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  @InterfaceAudience.Private<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  static RegionInfo parseFrom(final byte [] bytes, int offset, int len)<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  throws DeserializationException {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>      int pblen = ProtobufUtil.lengthOfPBMagic();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      try {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder();<a name="line.392"></a>
-<span class="sourceLineNo">393</span>        ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        HBaseProtos.RegionInfo ri = builder.build();<a name="line.394"></a>
-<span class="sourceLineNo">395</span>        return ProtobufUtil.toRegionInfo(ri);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      } catch (IOException e) {<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        throw new DeserializationException(e);<a name="line.397"></a>
-<span class="sourceLineNo">398</span>      }<a name="line.398"></a>
-<span class="sourceLineNo">399</span>    } else {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      throw new DeserializationException("PB encoded RegionInfo expected");<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><a name="line.403"></a>
-<span class="sourceLineNo">404</span>  /**<a name="line.404"></a>
-<span class="sourceLineNo">405</span>   * Check whether two regions are adjacent<a name="line.405"></a>
-<span class="sourceLineNo">406</span>   * @param regionA<a name="line.406"></a>
-<span class="sourceLineNo">407</span>   * @param regionB<a name="line.407"></a>
-<span class="sourceLineNo">408</span>   * @return true if two regions are adjacent<a name="line.408"></a>
-<span class="sourceLineNo">409</span>   */<a name="line.409"></a>
-<span class="sourceLineNo">410</span>  static boolean areAdjacent(RegionInfo regionA, RegionInfo regionB) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    if (regionA == null || regionB == null) {<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      throw new IllegalArgumentException(<a name="line.412"></a>
-<span class="sourceLineNo">413</span>      "Can't check whether adjacent for null region");<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    }<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    RegionInfo a = regionA;<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    RegionInfo b = regionB;<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    if (Bytes.compareTo(a.getStartKey(), b.getStartKey()) &gt; 0) {<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      a = regionB;<a name="line.418"></a>
-<span class="sourceLineNo">419</span>      b = regionA;<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    }<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    if (Bytes.compareTo(a.getEndKey(), b.getStartKey()) == 0) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      return true;<a name="line.422"></a>
+<span class="sourceLineNo">021</span>import edu.umd.cs.findbugs.annotations.CheckForNull;<a name="line.21"></a>
+<span class="sourceLineNo">022</span><a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.io.DataInputStream;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import java.io.IOException;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import java.util.ArrayList;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import java.util.Arrays;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import java.util.Comparator;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import java.util.List;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import java.util.stream.Collectors;<a name="line.29"></a>
+<span class="sourceLineNo">030</span><a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.HConstants;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.TableName;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.exceptions.DeserializationException;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.util.ByteArrayHashKey;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.util.HashKey;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.util.JenkinsHash;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.util.MD5Hash;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.hadoop.io.DataInputBuffer;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.apache.hadoop.util.StringUtils;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.41"></a>
+<span class="sourceLineNo">042</span><a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;<a name="line.44"></a>
+<span class="sourceLineNo">045</span><a name="line.45"></a>
+<span class="sourceLineNo">046</span>/**<a name="line.46"></a>
+<span class="sourceLineNo">047</span> * Information about a region. A region is a range of keys in the whole keyspace<a name="line.47"></a>
+<span class="sourceLineNo">048</span> * of a table, an identifier (a timestamp) for differentiating between subset<a name="line.48"></a>
+<span class="sourceLineNo">049</span> * ranges (after region split) and a replicaId for differentiating the instance<a name="line.49"></a>
+<span class="sourceLineNo">050</span> * for the same range and some status information about the region.<a name="line.50"></a>
+<span class="sourceLineNo">051</span> *<a name="line.51"></a>
+<span class="sourceLineNo">052</span> * The region has a unique name which consists of the following fields:<a name="line.52"></a>
+<span class="sourceLineNo">053</span> * &lt;ul&gt;<a name="line.53"></a>
+<span class="sourceLineNo">054</span> * &lt;li&gt; tableName   : The name of the table &lt;/li&gt;<a name="line.54"></a>
+<span class="sourceLineNo">055</span> * &lt;li&gt; startKey    : The startKey for the region. &lt;/li&gt;<a name="line.55"></a>
+<span class="sourceLineNo">056</span> * &lt;li&gt; regionId    : A timestamp when the region is created. &lt;/li&gt;<a name="line.56"></a>
+<span class="sourceLineNo">057</span> * &lt;li&gt; replicaId   : An id starting from 0 to differentiate replicas of the<a name="line.57"></a>
+<span class="sourceLineNo">058</span> * same region range but hosted in separated servers. The same region range can<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * be hosted in multiple locations.&lt;/li&gt;<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * &lt;li&gt; encodedName : An MD5 encoded string for the region name.&lt;/li&gt;<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * &lt;/ul&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> *<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;br&gt; Other than the fields in the region name, region info contains:<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;ul&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt; endKey      : the endKey for the region (exclusive) &lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt; split       : Whether the region is split &lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt; offline     : Whether the region is offline &lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
+<span class="sourceLineNo">070</span> */<a name="line.70"></a>
+<span class="sourceLineNo">071</span>@InterfaceAudience.Public<a name="line.71"></a>
+<span class="sourceLineNo">072</span>public interface RegionInfo {<a name="line.72"></a>
+<span class="sourceLineNo">073</span>  /**<a name="line.73"></a>
+<span class="sourceLineNo">074</span>   * Separator used to demarcate the encodedName in a region name<a name="line.74"></a>
+<span class="sourceLineNo">075</span>   * in the new format. See description on new format above.<a name="line.75"></a>
+<span class="sourceLineNo">076</span>   */<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  @InterfaceAudience.Private<a name="line.77"></a>
+<span class="sourceLineNo">078</span>  int ENC_SEPARATOR = '.';<a name="line.78"></a>
+<span class="sourceLineNo">079</span><a name="line.79"></a>
+<span class="sourceLineNo">080</span>  @InterfaceAudience.Private<a name="line.80"></a>
+<span class="sourceLineNo">081</span>  int MD5_HEX_LENGTH = 32;<a name="line.81"></a>
+<span class="sourceLineNo">082</span><a name="line.82"></a>
+<span class="sourceLineNo">083</span>  @InterfaceAudience.Private<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  int DEFAULT_REPLICA_ID = 0;<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  /**<a name="line.86"></a>
+<span class="sourceLineNo">087</span>   * to keep appended int's sorted in string format. Only allows 2 bytes<a name="line.87"></a>
+<span class="sourceLineNo">088</span>   * to be sorted for replicaId.<a name="line.88"></a>
+<span class="sourceLineNo">089</span>   */<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  @InterfaceAudience.Private<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  String REPLICA_ID_FORMAT = "%04X";<a name="line.91"></a>
+<span class="sourceLineNo">092</span><a name="line.92"></a>
+<span class="sourceLineNo">093</span>  @InterfaceAudience.Private<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  byte REPLICA_ID_DELIMITER = (byte)'_';<a name="line.94"></a>
+<span class="sourceLineNo">095</span><a name="line.95"></a>
+<span class="sourceLineNo">096</span>  @InterfaceAudience.Private<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  String INVALID_REGION_NAME_FORMAT_MESSAGE = "Invalid regionName format";<a name="line.97"></a>
+<span class="sourceLineNo">098</span><a name="line.98"></a>
+<span class="sourceLineNo">099</span>  @InterfaceAudience.Private<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  Comparator&lt;RegionInfo&gt; COMPARATOR<a name="line.100"></a>
+<span class="sourceLineNo">101</span>    = (RegionInfo lhs, RegionInfo rhs) -&gt; {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      if (rhs == null) {<a name="line.102"></a>
+<span class="sourceLineNo">103</span>        return 1;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>      }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>      // Are regions of same table?<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      int result = lhs.getTable().compareTo(rhs.getTable());<a name="line.107"></a>
+<span class="sourceLineNo">108</span>      if (result != 0) {<a name="line.108"></a>
+<span class="sourceLineNo">109</span>        return result;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>      }<a name="line.110"></a>
+<span class="sourceLineNo">111</span><a name="line.111"></a>
+<span class="sourceLineNo">112</span>      // Compare start keys.<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      result = Bytes.compareTo(lhs.getStartKey(), rhs.getStartKey());<a name="line.113"></a>
+<span class="sourceLineNo">114</span>      if (result != 0) {<a name="line.114"></a>
+<span class="sourceLineNo">115</span>        return result;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>      }<a name="line.116"></a>
+<span class="sourceLineNo">117</span><a name="line.117"></a>
+<span class="sourceLineNo">118</span>      // Compare end keys.<a name="line.118"></a>
+<span class="sourceLineNo">119</span>      result = Bytes.compareTo(lhs.getEndKey(), rhs.getEndKey());<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>      if (result != 0) {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>        if (lhs.getStartKey().length != 0<a name="line.122"></a>
+<span class="sourceLineNo">123</span>                &amp;&amp; lhs.getEndKey().length == 0) {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>            return 1; // this is last region<a name="line.124"></a>
+<span class="sourceLineNo">125</span>        }<a name="line.125"></a>
+<span class="sourceLineNo">126</span>        if (rhs.getStartKey().length != 0<a name="line.126"></a>
+<span class="sourceLineNo">127</span>                &amp;&amp; rhs.getEndKey().length == 0) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>            return -1; // o is the last region<a name="line.128"></a>
+<span class="sourceLineNo">129</span>        }<a name="line.129"></a>
+<span class="sourceLineNo">130</span>        return result;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>      }<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>      // regionId is usually milli timestamp -- this defines older stamps<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      // to be "smaller" than newer stamps in sort order.<a name="line.134"></a>
+<span class="sourceLineNo">135</span>      if (lhs.getRegionId() &gt; rhs.getRegionId()) {<a name="line.135"></a>
+<span class="sourceLineNo">136</span>        return 1;<a name="line.136"></a>
+<span class="sourceLineNo">137</span>      } else if (lhs.getRegionId() &lt; rhs.getRegionId()) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>        return -1;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>      }<a name="line.139"></a>
+<span class="sourceLineNo">140</span><a name="line.140"></a>
+<span class="sourceLineNo">141</span>      int replicaDiff = lhs.getReplicaId() - rhs.getReplicaId();<a name="line.141"></a>
+<span class="sourceLineNo">142</span>      if (replicaDiff != 0) return replicaDiff;<a name="line.142"></a>
+<span class="sourceLineNo">143</span><a name="line.143"></a>
+<span class="sourceLineNo">144</span>      if (lhs.isOffline() == rhs.isOffline())<a name="line.144"></a>
+<span class="sourceLineNo">145</span>        return 0;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>      if (lhs.isOffline() == true) return -1;<a name="line.146"></a>
+<span class="sourceLineNo">147</span><a name="line.147"></a>
+<span class="sourceLineNo">148</span>      return 1;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  };<a name="line.149"></a>
+<span class="sourceLineNo">150</span><a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * @return Return a short, printable name for this region<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * (usually encoded name) for us logging.<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  String getShortNameToLog();<a name="line.156"></a>
+<span class="sourceLineNo">157</span><a name="line.157"></a>
+<span class="sourceLineNo">158</span>  /**<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   * @return the regionId.<a name="line.159"></a>
+<span class="sourceLineNo">160</span>   */<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  long getRegionId();<a name="line.161"></a>
+<span class="sourceLineNo">162</span><a name="line.162"></a>
+<span class="sourceLineNo">163</span>  /**<a name="line.163"></a>
+<span class="sourceLineNo">164</span>   * @return the regionName as an array of bytes.<a name="line.164"></a>
+<span class="sourceLineNo">165</span>   * @see #getRegionNameAsString()<a name="line.165"></a>
+<span class="sourceLineNo">166</span>   */<a name="line.166"></a>
+<span class="sourceLineNo">167</span>  byte [] getRegionName();<a name="line.167"></a>
+<span class="sourceLineNo">168</span><a name="line.168"></a>
+<span class="sourceLineNo">169</span>  /**<a name="line.169"></a>
+<span class="sourceLineNo">170</span>   * @return Region name as a String for use in logging, etc.<a name="line.170"></a>
+<span class="sourceLineNo">171</span>   */<a name="line.171"></a>
+<span class="sourceLineNo">172</span>  String getRegionNameAsString();<a name="line.172"></a>
+<span class="sourceLineNo">173</span><a name="line.173"></a>
+<span class="sourceLineNo">174</span>  /**<a name="line.174"></a>
+<span class="sourceLineNo">175</span>   * @return the encoded region name.<a name="line.175"></a>
+<span class="sourceLineNo">176</span>   */<a name="line.176"></a>
+<span class="sourceLineNo">177</span>  String getEncodedName();<a name="line.177"></a>
+<span class="sourceLineNo">178</span><a name="line.178"></a>
+<span class="sourceLineNo">179</span>  /**<a name="line.179"></a>
+<span class="sourceLineNo">180</span>   * @return the encoded region name as an array of bytes.<a name="line.180"></a>
+<span class="sourceLineNo">181</span>   */<a name="line.181"></a>
+<span class="sourceLineNo">182</span>  byte [] getEncodedNameAsBytes();<a name="line.182"></a>
+<span class="sourceLineNo">183</span><a name="line.183"></a>
+<span class="sourceLineNo">184</span>  /**<a name="line.184"></a>
+<span class="sourceLineNo">185</span>   * @return the startKey.<a name="line.185"></a>
+<span class="sourceLineNo">186</span>   */<a name="line.186"></a>
+<span class="sourceLineNo">187</span>  byte [] getStartKey();<a name="line.187"></a>
+<span class="sourceLineNo">188</span><a name="line.188"></a>
+<span class="sourceLineNo">189</span>  /**<a name="line.189"></a>
+<span class="sourceLineNo">190</span>   * @return the endKey.<a name="line.190"></a>
+<span class="sourceLineNo">191</span>   */<a name="line.191"></a>
+<span class="sourceLineNo">192</span>  byte [] getEndKey();<a name="line.192"></a>
+<span class="sourceLineNo">193</span><a name="line.193"></a>
+<span class="sourceLineNo">194</span>  /**<a name="line.194"></a>
+<span class="sourceLineNo">195</span>   * @return current table name of the region<a name="line.195"></a>
+<span class="sourceLineNo">196</span>   */<a name="line.196"></a>
+<span class="sourceLineNo">197</span>  TableName getTable();<a name="line.197"></a>
+<span class="sourceLineNo">198</span><a name="line.198"></a>
+<span class="sourceLineNo">199</span>  /**<a name="line.199"></a>
+<span class="sourceLineNo">200</span>   * @return returns region replica id<a name="line.200"></a>
+<span class="sourceLineNo">201</span>   */<a name="line.201"></a>
+<span class="sourceLineNo">202</span>  int getReplicaId();<a name="line.202"></a>
+<span class="sourceLineNo">203</span><a name="line.203"></a>
+<span class="sourceLineNo">204</span>  /**<a name="line.204"></a>
+<span class="sourceLineNo">205</span>   * @return True if has been split and has daughters.<a name="line.205"></a>
+<span class="sourceLineNo">206</span>   */<a name="line.206"></a>
+<span class="sourceLineNo">207</span>  boolean isSplit();<a name="line.207"></a>
+<span class="sourceLineNo">208</span><a name="line.208"></a>
+<span class="sourceLineNo">209</span>  /**<a name="line.209"></a>
+<span class="sourceLineNo">210</span>   * @return True if this region is offline.<a name="line.210"></a>
+<span class="sourceLineNo">211</span>   */<a name="line.211"></a>
+<span class="sourceLineNo">212</span>  boolean isOffline();<a name="line.212"></a>
+<span class="sourceLineNo">213</span><a name="line.213"></a>
+<span class="sourceLineNo">214</span>  /**<a name="line.214"></a>
+<span class="sourceLineNo">215</span>   * @return True if this is a split parent region.<a name="line.215"></a>
+<span class="sourceLineNo">216</span>   */<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  boolean isSplitParent();<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  /**<a name="line.219"></a>
+<span class="sourceLineNo">220</span>   * @return true if this region is a meta region.<a name="line.220"></a>
+<span class="sourceLineNo">221</span>   */<a name="line.221"></a>
+<span class="sourceLineNo">222</span>  boolean isMetaRegion();<a name="line.222"></a>
+<span class="sourceLineNo">223</span><a name="line.223"></a>
+<span class="sourceLineNo">224</span>  /**<a name="line.224"></a>
+<span class="sourceLineNo">225</span>   * @param rangeStartKey<a name="line.225"></a>
+<span class="sourceLineNo">226</span>   * @param rangeEndKey<a name="line.226"></a>
+<span class="sourceLineNo">227</span>   * @return true if the given inclusive range of rows is fully contained<a name="line.227"></a>
+<span class="sourceLineNo">228</span>   * by this region. For example, if the region is foo,a,g and this is<a name="line.228"></a>
+<span class="sourceLineNo">229</span>   * passed ["b","c"] or ["a","c"] it will return true, but if this is passed<a name="line.229"></a>
+<span class="sourceLineNo">230</span>   * ["b","z"] it will return false.<a name="line.230"></a>
+<span class="sourceLineNo">231</span>   * @throws IllegalArgumentException if the range passed is invalid (ie. end &amp;lt; start)<a name="line.231"></a>
+<span class="sourceLineNo">232</span>   */<a name="line.232"></a>
+<span class="sourceLineNo">233</span>  boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey);<a name="line.233"></a>
+<span class="sourceLineNo">234</span><a name="line.234"></a>
+<span class="sourceLineNo">235</span>  /**<a name="line.235"></a>
+<span class="sourceLineNo">236</span>   * @param row<a name="line.236"></a>
+<span class="sourceLineNo">237</span>   * @return true if the given row falls in this region.<a name="line.237"></a>
+<span class="sourceLineNo">238</span>   */<a name="line.238"></a>
+<span class="sourceLineNo">239</span>  boolean containsRow(byte[] row);<a name="line.239"></a>
+<span class="sourceLineNo">240</span><a name="line.240"></a>
+<span class="sourceLineNo">241</span>  /**<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Does region name contain its encoded name?<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * @param regionName region name<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   * @return boolean indicating if this a new format region<a name="line.244"></a>
+<span class="sourceLineNo">245</span>   *         name which contains its encoded name.<a name="line.245"></a>
+<span class="sourceLineNo">246</span>   */<a name="line.246"></a>
+<span class="sourceLineNo">247</span>  @InterfaceAudience.Private<a name="line.247"></a>
+<span class="sourceLineNo">248</span>  static boolean hasEncodedName(final byte[] regionName) {<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    // check if region name ends in ENC_SEPARATOR<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    return (regionName.length &gt;= 1) &amp;&amp;<a name="line.250"></a>
+<span class="sourceLineNo">251</span>      (regionName[regionName.length - 1] == RegionInfo.ENC_SEPARATOR);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>  }<a name="line.252"></a>
+<span class="sourceLineNo">253</span><a name="line.253"></a>
+<span class="sourceLineNo">254</span>  /**<a name="line.254"></a>
+<span class="sourceLineNo">255</span>   * @return the encodedName<a name="line.255"></a>
+<span class="sourceLineNo">256</span>   */<a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @InterfaceAudience.Private<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  static String encodeRegionName(final byte [] regionName) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    String encodedName;<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    if (hasEncodedName(regionName)) {<a name="line.260"></a>
+<span class="sourceLineNo">261</span>      // region is in new format:<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      // &lt;tableName&gt;,&lt;startKey&gt;,&lt;regionIdTimeStamp&gt;/encodedName/<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      encodedName = Bytes.toString(regionName,<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      regionName.length - MD5_HEX_LENGTH - 1,<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      MD5_HEX_LENGTH);<a name="line.265"></a>
+<span class="sourceLineNo">266</span>    } else {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      // old format region name. First hbase:meta region also<a name="line.267"></a>
+<span class="sourceLineNo">268</span>      // use this format.EncodedName is the JenkinsHash value.<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      HashKey&lt;byte[]&gt; key = new ByteArrayHashKey(regionName, 0, regionName.length);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>      int hashVal = Math.abs(JenkinsHash.getInstance().hash(key, 0));<a name="line.270"></a>
+<span class="sourceLineNo">271</span>      encodedName = String.valueOf(hashVal);<a name="line.271"></a>
+<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
+<span class="sourceLineNo">273</span>    return encodedName;<a name="line.273"></a>
+<span class="sourceLineNo">274</span>  }<a name="line.274"></a>
+<span class="sourceLineNo">275</span><a name="line.275"></a>
+<span class="sourceLineNo">276</span>  @InterfaceAudience.Private<a name="line.276"></a>
+<span class="sourceLineNo">277</span>  static String getRegionNameAsString(byte[] regionName) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>    return getRegionNameAsString(null, regionName);<a name="line.278"></a>
+<span class="sourceLineNo">279</span>  }<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>  @InterfaceAudience.Private<a name="line.281"></a>
+<span class="sourceLineNo">282</span>  static String getRegionNameAsString(@CheckForNull RegionInfo ri, byte[] regionName) {<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    if (RegionInfo.hasEncodedName(regionName)) {<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      // new format region names already have their encoded name.<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return Bytes.toStringBinary(regionName);<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    // old format. regionNameStr doesn't have the region name.<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    if (ri == null) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>      return Bytes.toStringBinary(regionName) + "." + RegionInfo.encodeRegionName(regionName);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>    } else {<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      return Bytes.toStringBinary(regionName) + "." + ri.getEncodedName();<a name="line.292"></a>
+<span class="sourceLineNo">293</span>    }<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
+<span class="sourceLineNo">295</span><a name="line.295"></a>
+<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
+<span class="sourceLineNo">297</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>   * (usually encoded name) for us logging.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>   */<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  static String getShortNameToLog(RegionInfo...hris) {<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    return getShortNameToLog(Arrays.asList(hris));<a name="line.301"></a>
+<span class="sourceLineNo">302</span>  }<a name="line.302"></a>
+<span class="sourceLineNo">303</span><a name="line.303"></a>
+<span class="sourceLineNo">304</span>  /**<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   * @return Return a String of short, printable names for &lt;code&gt;hris&lt;/code&gt;<a name="line.305"></a>
+<span class="sourceLineNo">306</span>   * (usually encoded name) for us logging.<a name="line.306"></a>
+<span class="sourceLineNo">307</span>   */<a name="line.307"></a>
+<span class="sourceLineNo">308</span>  static String getShortNameToLog(final List&lt;RegionInfo&gt; ris) {<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    return ris.stream().map(ri -&gt; ri.getShortNameToLog()).<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    collect(Collectors.toList()).toString();<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  }<a name="line.311"></a>
+<span class="sourceLineNo">312</span><a name="line.312"></a>
+<span class="sourceLineNo">313</span>  /**<a name="line.313"></a>
+<span class="sourceLineNo">314</span>   * Gets the table name from the specified region name.<a name="line.314"></a>
+<span class="sourceLineNo">315</span>   * @param regionName to extract the table name from<a name="line.315"></a>
+<span class="sourceLineNo">316</span>   * @return Table name<a name="line.316"></a>
+<span class="sourceLineNo">317</span>   */<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  @InterfaceAudience.Private<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // This method should never be used. Its awful doing parse from bytes.<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // It is fallback in case we can't get the tablename any other way. Could try removing it.<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // Keeping it Audience Private so can remove at later date.<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  static TableName getTable(final byte [] regionName) {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    int offset = -1;<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    for (int i = 0; i &lt; regionName.length; i++) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      if (regionName[i] == HConstants.DELIMITER) {<a name="line.325"></a>
+<span class="sourceLineNo">326</span>        offset = i;<a name="line.326"></a>
+<span class="sourceLineNo">327</span>        break;<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    }<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    if (offset &lt;= 0) {<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      throw new IllegalArgumentException("offset=" + offset);<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    }<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    byte[] buff  = new byte[offset];<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    System.arraycopy(regionName, 0, buff, 0, offset);<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    return TableName.valueOf(buff);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>  }<a name="line.336"></a>
+<span class="sourceLineNo">337</span><a name="line.337"></a>
+<span class="sourceLineNo">338</span>  /**<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * Gets the start key from the specified region name.<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * @param regionName<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   * @return Start key.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>   * @throws java.io.IOException<a name="line.342"></a>
+<span class="sourceLineNo">343</span>   */<a name="line.343"></a>
+<span class="sourceLineNo">344</span>  static byte[] getStartKey(final byte[] regionName) throws IOException {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    return parseRegionName(regionName)[1];<a name="line.345"></a>
+<span class="sourceLineNo">346</span>  }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>  @InterfaceAudience.Private<a name="line.348"></a>
+<span class="sourceLineNo">349</span>  static boolean isEncodedRegionName(byte[] regionName) throws IOException {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    try {<a name="line.350"></a>
+<span class="sourceLineNo">351</span>      parseRegionName(regionName);<a name="line.351"></a>
+<span class="sourceLineNo">352</span>      return false;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    } catch (IOException e) {<a name="line.353"></a>
+<span class="sourceLineNo">354</span>      if (StringUtils.stringifyException(e)<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      .contains(INVALID_REGION_NAME_FORMAT_MESSAGE)) {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        return true;<a name="line.356"></a>
+<span class="sourceLineNo">357</span>      }<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      throw e;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    }<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>  /**<a name="line.362"></a>
+<span class="sourceLineNo">363</span>   * @param bytes<a name="line.363"></a>
+<span class="sourceLineNo">364</span>   * @return A deserialized {@link RegionInfo}<a name="line.364"></a>
+<span class="sourceLineNo">365</span>   * or null if we failed deserialize or passed bytes null<a name="line.365"></a>
+<span class="sourceLineNo">366</span>   */<a name="line.366"></a>
+<span class="sourceLineNo">367</span>  @InterfaceAudience.Private<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  static RegionInfo parseFromOrNull(final byte [] bytes) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    if (bytes == null) return null;<a name="line.369"></a>
+<span class="sourceLineNo">370</span>    return parseFromOrNull(bytes, 0, bytes.length);<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>   * @param bytes<a name="line.374"></a>
+<span class="sourceLineNo">375</span>   * @param offset<a name="line.375"></a>
+<span class="sourceLineNo">376</span>   * @param len<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * @return A deserialized {@link RegionInfo} or null<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   *  if we failed deserialize or passed bytes null<a name="line.378"></a>
+<span class="sourceLineNo">379</span>   */<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  @InterfaceAudience.Private<a name="line.380"></a>
+<span class="sourceLineNo">381</span>  static RegionInfo parseFromOrNull(final byte [] bytes, int offset, int len) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    if (bytes == null || len &lt;= 0) return null;<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    try {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      return parseFrom(bytes, offset, len);<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    } catch (DeserializationException e) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      return null;<a name="line.386"></a>
+<span class="sourceLineNo">387</span>    }<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  }<a name="line.388"></a>
+<span class="sourceLineNo">389</span><a name="line.389"></a>
+<span class="sourceLineNo">390</span>  /**<a name="line.390"></a>
+<span class="sourceLineNo">391</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.391"></a>
+<span class="sourceLineNo">392</span>   * @return A deserialized {@link RegionInfo}<a name="line.392"></a>
+<span class="sourceLineNo">393</span>   * @throws DeserializationException<a name="line.393"></a>
+<span class="sourceLineNo">394</span>   */<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  @InterfaceAudience.Private<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  static RegionInfo parseFrom(final byte [] bytes) throws DeserializationException {<a name="line.396"></a>
+<span class="sourceLineNo">397</span>    if (bytes == null) return null;<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    return parseFrom(bytes, 0, bytes.length);<a name="line.398"></a>
+<span class="sourceLineNo">399</span>  }<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>  /**<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * @param bytes A pb RegionInfo serialized with a pb magic prefix.<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * @param offset starting point in the byte array<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * @param len length to read on the byte array<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   * @return A deserialized {@link RegionInfo}<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * @throws DeserializationException<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   */<a name="line.407"></a>
+<span class="sourceLineNo">408</span>  @InterfaceAudience.Private<a name="line.408"></a>
+<span class="sourceLineNo">409</span>  static RegionInfo parseFrom(final byte [] bytes, int offset, int len)<a name="line.409"></a>
+<span class="sourceLineNo">410</span>  throws DeserializationException {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>    if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) {<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      int pblen = ProtobufUtil.lengthOfPBMagic();<a name="line.412"></a>
+<span class="sourceLineNo">413</span>      try {<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder();<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen);<a name="line.415"></a>
+<span class="sourceLineNo">416</span>        HBaseProtos.RegionInfo ri = builder.build();<a name="line.416"></a>
+<span class="sourceLineNo">417</span>        return ProtobufUtil.toRegionInfo(ri);<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      } catch (IOException e) {<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        throw new DeserializationException(e);<a name="line.419"></a>
+<span class="sourceLineNo">420</span>      }<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    } else {<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      throw new DeserializationException("PB encoded RegionInfo expected");<a name="line.422"></a>
 <span class="sourceLineNo">423</span>    }<a name="line.423"></a>
-<span class="sourceLineNo">424</span>    return false;<a name="line.424"></a>
-<span class="sourceLineNo">425</span>  }<a name="line.425"></a>
-<span class="sourceLineNo">426</span><a name="line.426"></a>
-<span class="sourceLineNo">427</span>  /**<a name="line.427"></a>
-<span class="sourceLineNo">428</span>   * @param ri<a name="line.428"></a>
-<span class="sourceLineNo">429</span>   * @return This instance serialized as protobuf w/ a magic pb prefix.<a name="line.429"></a>
-<span class="sourceLineNo">430</span>   * @see #parseFrom(byte[])<a name="line.430"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  /**<a name="line.426"></a>
+<span class="sourceLineNo">427</span>   * Check whether two regions are adjacent<a name="line.427"></a>
+<span class="sourceLineNo">428</span>   * @param regionA<a name="line.428"></a>
+<span class="sourceLineNo">429</span>   * @param regionB<a name="line.429"></a>
+<span class="sourceLineNo">430</span>   * @return true if two regions are adjacent<a name="line.430"></a>
 <span class="sourceLineNo">431</span>   */<a name="line.431"></a>
-<span class="sourceLineNo">432</span>  static byte [] toByteArray(RegionInfo ri) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    byte [] bytes = ProtobufUtil.toRegionInfo(ri).toByteArray();<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    return ProtobufUtil.prependPBMagic(bytes);<a name="line.434"></a>
-<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
-<span class="sourceLineNo">436</span><a name="line.436"></a>
-<span class="sourceLineNo">437</span>  /**<a name="line.437"></a>
-<span class="sourceLineNo">438</span>   * Use logging.<a name="line.438"></a>
-<span class="sourceLineNo">439</span>   * @param encodedRegionName The encoded regionname.<a name="line.439"></a>
-<span class="sourceLineNo">440</span>   * @return &lt;code&gt;hbase:meta&lt;/code&gt; if passed &lt;code&gt;1028785192&lt;/code&gt; else returns<a name="line.440"></a>
-<span class="sourceLineNo">441</span>   * &lt;code&gt;encodedRegionName&lt;/code&gt;<a name="line.441"></a>
-<span class="sourceLineNo">442</span>   */<a name="line.442"></a>
-<span class="sourceLineNo">443</span>  static String prettyPrint(final String encodedRegionName) {<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    if (encodedRegionName.equals("1028785192")) {<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      return encodedRegionName + "/hbase:meta";<a name="line.445"></a>
-<span class="sourceLineNo">446</span>    }<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    return encodedRegionName;<a name="line.447"></a>
-<span class="sourceLineNo">448</span>  }<a name="line.448"></a>
-<span class="sourceLineNo">449</span><a name="line.449"></a>
-<span class="sourceLineNo">450</span>  /**<a name="line.450"></a>
-<span class="sourceLineNo">451</span>   * Make a region name of passed parameters.<a name="line.451"></a>
-<span class="sourceLineNo">452</span>   * @param tableName<a name="line.452"></a>
-<span class="sourceLineNo">453</span>   * @param startKey Can be null<a name="line.453"></a>
-<span class="sourceLineNo">454</span>   * @param regionid Region id (Usually timestamp from when region was created).<a name="line.454"></a>
-<span class="sourceLineNo">455</span>   * @param newFormat should we create the region name in the new format<a name="line.455"></a>
-<span class="sourceLineNo">456</span>   *                  (such that it contains its encoded name?).<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * @return Region name made of passed tableName, startKey and id<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   */<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  static byte [] createRegionName(final TableName tableName, final byte[] startKey,<a name="line.459"></a>
-<span class="sourceLineNo">460</span>                                  final long regionid, boolean newFormat) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    return createRegionName(tableName, startKey, Long.toString(regionid), newFormat);<a name="line.461"></a>
-<span class="sourceLineNo">462</span>  }<a name="line.462"></a>
-<span class="sourceLineNo">463</span><a name="line.463"></a>
-<span class="sourceLineNo">464</span>  /**<a name="line.464"></a>
-<span class="sourceLineNo">465</span>   * Make a region name of passed parameters.<a name="line.465"></a>
-<span class="sourceLineNo">466</span>   * @param tableName<a name="line.466"></a>
-<span class="sourceLineNo">467</span>   * @param startKey Can be null<a name="line.467"></a>
-<span class="sourceLineNo">468</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.468"></a>
-<span class="sourceLineNo">469</span>   * @param newFormat should we create the region name in the new format<a name="line.469"></a>
-<span class="sourceLineNo">470</span>   *                  (such that it contains its encoded name?).<a name="line.470"></a>
-<span class="sourceLineNo">471</span>   * @return Region name made of passed tableName, startKey and id<a name="line.471"></a>
-<span class="sourceLineNo">472</span>   */<a name="line.472"></a>
-<span class="sourceLineNo">473</span>  static byte [] createRegionName(final TableName tableName,<a name="line.473"></a>
-<span class="sourceLineNo">474</span>                                  final byte[] startKey, final String id, boolean newFormat) {<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    return createRegionName(tableName, startKey, Bytes.toBytes(id), newFormat);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  }<a name="line.476"></a>
-<span class="sourceLineNo">477</span><a name="line.477"></a>
-<span class="sourceLineNo">478</span>  /**<a name="line.478"></a>
-<span class="sourceLineNo">479</span>   * Make a region name of passed parameters.<a name="line.479"></a>
-<span class="sourceLineNo">480</span>   * @param tableName<a name="line.480"></a>
-<span class="sourceLineNo">481</span>   * @param startKey Can be null<a name="line.481"></a>
-<span class="sourceLineNo">482</span>   * @param regionid Region id (Usually timestamp from when region was created).<a name="line.482"></a>
-<span class="sourceLineNo">483</span>   * @param replicaId<a name="line.483"></a>
-<span class="sourceLineNo">484</span>   * @param newFormat should we create the region name in the new format<a name="line.484"></a>
-<span class="sourceLineNo">485</span>   *                  (such that it contains its encoded name?).<a name="line.485"></a>
-<span class="sourceLineNo">486</span>   * @return Region name made of passed tableName, startKey, id and replicaId<a name="line.486"></a>
-<span class="sourceLineNo">487</span>   */<a name="line.487"></a>
-<span class="sourceLineNo">488</span>  static byte [] createRegionName(final TableName tableName,<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      final byte[] startKey, final long regionid, int replicaId, boolean newFormat) {<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    return createRegionName(tableName, startKey, Bytes.toBytes(Long.toString(regionid)),<a name="line.490"></a>
-<span class="sourceLineNo">491</span>      replicaId, newFormat);<a name="line.491"></a>
-<span class="sourceLineNo">492</span>  }<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>  /**<a name="line.494"></a>
-<span class="sourceLineNo">495</span>   * Make a region name of passed parameters.<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * @param tableName<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * @param startKey Can be null<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param newFormat should we create the region name in the new format<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   *                  (such that it contains its encoded name?).<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   * @return Region name made of passed tableName, startKey and id<a name="line.501"></a>
-<span class="sourceLineNo">502</span>   */<a name="line.502"></a>
-<span class="sourceLineNo">503</span>  static byte [] createRegionName(final TableName tableName,<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      final byte[] startKey, final byte[] id, boolean newFormat) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    return createRegionName(tableName, startKey, id, DEFAULT_REPLICA_ID, newFormat);<a name="line.505"></a>
-<span class="sourceLineNo">506</span>  }<a name="line.506"></a>
-<span class="sourceLineNo">507</span><a name="line.507"></a>
-<span class="sourceLineNo">508</span>  /**<a name="line.508"></a>
-<span class="sourceLineNo">509</span>   * Make a region name of passed parameters.<a name="line.509"></a>
-<span class="sourceLineNo">510</span>   * @param tableName<a name="line.510"></a>
-<span class="sourceLineNo">511</span>   * @param startKey Can be null<a name="line.511"></a>
-<span class="sourceLineNo">512</span>   * @param id Region id (Usually timestamp from when region was created).<a name="line.512"></a>
-<span class="sourceLineNo">513</span>   * @param replicaId<a name="line.513"></a>
-<span class="sourceLineNo">514</span>   * @param newFormat should we create the region name in the new format<a name="line.514"></a>
-<span class="sourceLineNo">515</span>   * @return Region name made of passed tableName, startKey, id and replicaId<a name="line.515"></a>
-<span class="sourceLineNo">516</span>   */<a name="line.516"></a>
-<span class="sourceLineNo">517</span>  static byte [] createRegionName(final TableName tableName,<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      final byte[] startKey, final byte[] id, final int replicaId, boolean newFormat) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    int len = tableName.getName().length + 2 + id.length + (startKey == null? 0: startKey.length);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>    if (newFormat) {<a name="line.520"></a>
-<span class="sourceLineNo">521</span>      len += MD5_HEX_LENGTH + 2;<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    }<a name="line.522"></a>
-<span class="sourceLineNo">523</span>    byte[] replicaIdBytes = null;<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    // Special casing: replicaId is only appended if replicaId is greater than<a name="line.524"></a>
-<span class="sourceLineNo">525</span>    // 0. This is because all regions in meta would have to be migrated to the new<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    // name otherwise<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    if (replicaId &gt; 0) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>      // use string representation for replica id<a name="line.528"></a>
-<span class="sourceLineNo">529</span>      replicaIdBytes = Bytes.toBytes(String.format(REPLICA_ID_FORMAT, replicaId));<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      len += 1 + replicaIdBytes.length;<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    }<a name="line.531"></a>
-<span class="sourceLineNo">532</span><a name="line.532"></a>
-<span class="sourceLineNo">533</span>    byte [] b = new byte [len];<a name="line.533"></a>
-<span class="sourceLineNo">534</span><a name="line.534"></a>
-<span class="sourceLineNo">535</span>    int offset = tableName.getName().length;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    System.arraycopy(tableName.getName(), 0, b, 0, offset);<a name="line.536"></a>
-<span class="sourceLineNo">537</span>    b[offset++] = HConstants.DELIMITER;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    if (startKey != null &amp;&amp; startKey.length &gt; 0) {<a name="line.538"></a>
-<span class="sourceLineNo">539</span>      System.arraycopy(startKey, 0, b, offset, startKey.length);<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      offset += startKey.length;<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    }<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    b[offset++] = HConstants.DELIMITER;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>    System.arraycopy(id, 0, b, offset, id.length);<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    offset += id.length;<a name="line.544"></a>
-<span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (replicaIdBytes != null) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      b[offset++] = REPLICA_ID_DELIMITER;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      System.arraycopy(replicaIdBytes, 0, b, offset, replicaIdBytes.length);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>      offset += replicaIdBytes.length;<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    }<a name="line.550"></a>
-<span class="sourceLineNo">551</span><a name="line.551"></a>
-<span class="sourceLineNo">552</span>    if (newFormat) {<a name="line.552"></a>
-<span class="sourceLineNo">553</span>      //<a name="line.553"></a>
-<span class="sourceLineNo">554</span>      // Encoded name should be built into the region name.<a name="line.554"></a>
-<span class="sourceLineNo">555</span>      //<a name="line.555"></a>
-<span class="sourceLineNo">556</span>      // Use the region name thus far (namely, &lt;tablename&gt;,&lt;startKey&gt;,&lt;id&gt;_&lt;replicaId&gt;)<a name="line.556"></a>
-<span class="sourceLineNo">557</span>      // to compute a MD5 hash to be used as the encoded name, and append<a name="line.557"></a>
-<span class="sourceLineNo">558</span>      // it to the byte buffer.<a name="line.558"></a>
-<span class="sourceLineNo">559</span>      //<a name="line.559"></a>
-<span class="sourceLineNo">560</span>      String md5Hash = MD5Hash.getMD5AsHex(b, 0, offset);<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      byte [] md5HashBytes = Bytes.toBytes(md5Hash);<a name="line.561"></a>
-<span class="sourceLineNo">562</span><a name="line.562"></a>
-<span class="sourceLineNo">563</span>      if (md5HashBytes.length != MD5_HEX_LENGTH) {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>        System.out.println("MD5-hash length mismatch: Expected=" + MD5_HEX_LENGTH +<a name="line.564"></a>
-<span class="sourceLineNo">565</span>        "; Got=" + md5HashBytes.length);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      }<a name="line.566"></a>
+<span class="sourceLineNo">432</span>  static boolean areAdj

<TRUNCATED>

[02/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
index 006d1ba..18cf507 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.FailInitializeDummyReplicationSource.html
@@ -654,258 +654,274 @@
 <span class="sourceLineNo">646</span>    }<a name="line.646"></a>
 <span class="sourceLineNo">647</span>  }<a name="line.647"></a>
 <span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>  /**<a name="line.649"></a>
-<span class="sourceLineNo">650</span>   * Add a peer and wait for it to initialize<a name="line.650"></a>
-<span class="sourceLineNo">651</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.651"></a>
-<span class="sourceLineNo">652</span>   */<a name="line.652"></a>
-<span class="sourceLineNo">653</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.653"></a>
-<span class="sourceLineNo">654</span>      final boolean waitForSource) throws Exception {<a name="line.654"></a>
-<span class="sourceLineNo">655</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>    try {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      manager.addPeer(peerId);<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    } catch (Exception e) {<a name="line.659"></a>
-<span class="sourceLineNo">660</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>    waitPeer(peerId, manager, waitForSource);<a name="line.662"></a>
-<span class="sourceLineNo">663</span>    if (managerOfCluster != null) {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      managerOfCluster.addPeer(peerId);<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>  }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>  private static void waitPeer(final String peerId,<a name="line.669"></a>
-<span class="sourceLineNo">670</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>      if (waitForSource) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>        if (rs == null) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          return false;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        }<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.678"></a>
-<span class="sourceLineNo">679</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>        return true;<a name="line.681"></a>
-<span class="sourceLineNo">682</span>      } else {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>        return (rp.getPeer(peerId) != null);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      }<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    });<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>  /**<a name="line.688"></a>
-<span class="sourceLineNo">689</span>   * Remove a peer and wait for it to get cleaned up<a name="line.689"></a>
-<span class="sourceLineNo">690</span>   * @param peerId<a name="line.690"></a>
-<span class="sourceLineNo">691</span>   * @throws Exception<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      try {<a name="line.697"></a>
-<span class="sourceLineNo">698</span>        manager.removePeer(peerId);<a name="line.698"></a>
-<span class="sourceLineNo">699</span>      } catch (Exception e) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        // ignore the failed exception and continue.<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      }<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      @Override<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      public boolean evaluate() throws Exception {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<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>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.713"></a>
-<span class="sourceLineNo">714</span>    // 1. Create store files for the families<a name="line.714"></a>
-<span class="sourceLineNo">715</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.718"></a>
-<span class="sourceLineNo">719</span>    p.add(hfilePath1);<a name="line.719"></a>
-<span class="sourceLineNo">720</span>    try {<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    } catch (IOException e) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    }<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    storeFiles.put(f1, p);<a name="line.726"></a>
-<span class="sourceLineNo">727</span>    scope.put(f1, 1);<a name="line.727"></a>
-<span class="sourceLineNo">728</span>    p = new ArrayList&lt;&gt;(1);<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.729"></a>
-<span class="sourceLineNo">730</span>    p.add(hfilePath2);<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    try {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    } catch (IOException e) {<a name="line.733"></a>
-<span class="sourceLineNo">734</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>    storeFiles.put(f2, p);<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    // 2. Create bulk load descriptor<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    BulkLoadDescriptor desc =<a name="line.739"></a>
-<span class="sourceLineNo">740</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.740"></a>
-<span class="sourceLineNo">741</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.741"></a>
-<span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    // 3. create bulk load wal edit event<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    return logEdit;<a name="line.745"></a>
-<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>  static class DummyNodeFailoverWorker extends Thread {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    Server server;<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    private ServerName deadRS;<a name="line.751"></a>
-<span class="sourceLineNo">752</span>    ReplicationQueueStorage rq;<a name="line.752"></a>
-<span class="sourceLineNo">753</span><a name="line.753"></a>
-<span class="sourceLineNo">754</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      this.deadRS = deadRS;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      this.server = s;<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.757"></a>
-<span class="sourceLineNo">758</span>        server.getConfiguration());<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>    @Override<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    public void run() {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>      try {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.764"></a>
-<span class="sourceLineNo">765</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>        for (String queue : queues) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.768"></a>
-<span class="sourceLineNo">769</span>          if (pair != null) {<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>      } catch (Exception e) {<a name="line.774"></a>
-<span class="sourceLineNo">775</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      } finally {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>        latch.countDown();<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    /**<a name="line.781"></a>
-<span class="sourceLineNo">782</span>     * @return 1 when the map is not empty.<a name="line.782"></a>
-<span class="sourceLineNo">783</span>     */<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    private int isLogZnodesMapPopulated() {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>      if (sets.size() &gt; 1) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      }<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (sets.size() == 1) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.790"></a>
-<span class="sourceLineNo">791</span>        for (String file : files) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>          // at least one file was missing<a name="line.792"></a>
-<span class="sourceLineNo">793</span>          if (!s.contains(file)) {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>            return 0;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>          }<a name="line.795"></a>
-<span class="sourceLineNo">796</span>        }<a name="line.796"></a>
-<span class="sourceLineNo">797</span>        return 1; // we found all the files<a name="line.797"></a>
-<span class="sourceLineNo">798</span>      }<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return 0;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span><a name="line.802"></a>
-<span class="sourceLineNo">803</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.803"></a>
-<span class="sourceLineNo">804</span><a name="line.804"></a>
-<span class="sourceLineNo">805</span>    @Override<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.808"></a>
-<span class="sourceLineNo">809</span>        throws IOException {<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      throw new IOException("Failing deliberately");<a name="line.810"></a>
-<span class="sourceLineNo">811</span>    }<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>  static class DummyServer implements Server {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    String hostname;<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>    DummyServer() {<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      hostname = "hostname.example.org";<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    }<a name="line.819"></a>
+<span class="sourceLineNo">649</span>  @Test<a name="line.649"></a>
+<span class="sourceLineNo">650</span>  public void testSameWALPrefix() throws IOException {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    Set&lt;String&gt; latestWalsBefore =<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      manager.getLastestPath().stream().map(Path::getName).collect(Collectors.toSet());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    String walName1 = "localhost,8080,12345-45678-Peer.34567";<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    String walName2 = "localhost,8080,12345.56789";<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    manager.preLogRoll(new Path(walName1));<a name="line.655"></a>
+<span class="sourceLineNo">656</span>    manager.preLogRoll(new Path(walName2));<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>    Set&lt;String&gt; latestWals = manager.getLastestPath().stream().map(Path::getName)<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      .filter(n -&gt; !latestWalsBefore.contains(n)).collect(Collectors.toSet());<a name="line.659"></a>
+<span class="sourceLineNo">660</span>    assertEquals(2, latestWals.size());<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    assertTrue(latestWals.contains(walName1));<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    assertTrue(latestWals.contains(walName2));<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  /**<a name="line.665"></a>
+<span class="sourceLineNo">666</span>   * Add a peer and wait for it to initialize<a name="line.666"></a>
+<span class="sourceLineNo">667</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.667"></a>
+<span class="sourceLineNo">668</span>   */<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.669"></a>
+<span class="sourceLineNo">670</span>      final boolean waitForSource) throws Exception {<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    try {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      manager.addPeer(peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    } catch (Exception e) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    waitPeer(peerId, manager, waitForSource);<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    if (managerOfCluster != null) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      managerOfCluster.addPeer(peerId);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    }<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>  private static void waitPeer(final String peerId,<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.688"></a>
+<span class="sourceLineNo">689</span>      if (waitForSource) {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        if (rs == null) {<a name="line.691"></a>
+<span class="sourceLineNo">692</span>          return false;<a name="line.692"></a>
+<span class="sourceLineNo">693</span>        }<a name="line.693"></a>
+<span class="sourceLineNo">694</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.695"></a>
+<span class="sourceLineNo">696</span>        }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>        return true;<a name="line.697"></a>
+<span class="sourceLineNo">698</span>      } else {<a name="line.698"></a>
+<span class="sourceLineNo">699</span>        return (rp.getPeer(peerId) != null);<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      }<a name="line.700"></a>
+<span class="sourceLineNo">701</span>    });<a name="line.701"></a>
+<span class="sourceLineNo">702</span>  }<a name="line.702"></a>
+<span class="sourceLineNo">703</span><a name="line.703"></a>
+<span class="sourceLineNo">704</span>  /**<a name="line.704"></a>
+<span class="sourceLineNo">705</span>   * Remove a peer and wait for it to get cleaned up<a name="line.705"></a>
+<span class="sourceLineNo">706</span>   * @param peerId<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * @throws Exception<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   */<a name="line.708"></a>
+<span class="sourceLineNo">709</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.709"></a>
+<span class="sourceLineNo">710</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.711"></a>
+<span class="sourceLineNo">712</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.712"></a>
+<span class="sourceLineNo">713</span>      try {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>        manager.removePeer(peerId);<a name="line.714"></a>
+<span class="sourceLineNo">715</span>      } catch (Exception e) {<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        // ignore the failed exception and continue.<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      }<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    }<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      @Override<a name="line.720"></a>
+<span class="sourceLineNo">721</span>      public boolean evaluate() throws Exception {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.722"></a>
+<span class="sourceLineNo">723</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.723"></a>
+<span class="sourceLineNo">724</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      }<a name="line.725"></a>
+<span class="sourceLineNo">726</span>    });<a name="line.726"></a>
+<span class="sourceLineNo">727</span>  }<a name="line.727"></a>
+<span class="sourceLineNo">728</span><a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    // 1. Create store files for the families<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.731"></a>
+<span class="sourceLineNo">732</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    p.add(hfilePath1);<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    try {<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    } catch (IOException e) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>    storeFiles.put(f1, p);<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    scope.put(f1, 1);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    p = new ArrayList&lt;&gt;(1);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.745"></a>
+<span class="sourceLineNo">746</span>    p.add(hfilePath2);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    try {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    } catch (IOException e) {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    }<a name="line.752"></a>
+<span class="sourceLineNo">753</span>    storeFiles.put(f2, p);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // 2. Create bulk load descriptor<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    BulkLoadDescriptor desc =<a name="line.755"></a>
+<span class="sourceLineNo">756</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.757"></a>
+<span class="sourceLineNo">758</span><a name="line.758"></a>
+<span class="sourceLineNo">759</span>    // 3. create bulk load wal edit event<a name="line.759"></a>
+<span class="sourceLineNo">760</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.760"></a>
+<span class="sourceLineNo">761</span>    return logEdit;<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>  static class DummyNodeFailoverWorker extends Thread {<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    Server server;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    private ServerName deadRS;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    ReplicationQueueStorage rq;<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      this.deadRS = deadRS;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      this.server = s;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        server.getConfiguration());<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    }<a name="line.775"></a>
+<span class="sourceLineNo">776</span><a name="line.776"></a>
+<span class="sourceLineNo">777</span>    @Override<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    public void run() {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>      try {<a name="line.779"></a>
+<span class="sourceLineNo">780</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.780"></a>
+<span class="sourceLineNo">781</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.781"></a>
+<span class="sourceLineNo">782</span>        for (String queue : queues) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.783"></a>
+<span class="sourceLineNo">784</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.784"></a>
+<span class="sourceLineNo">785</span>          if (pair != null) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.789"></a>
+<span class="sourceLineNo">790</span>      } catch (Exception e) {<a name="line.790"></a>
+<span class="sourceLineNo">791</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.791"></a>
+<span class="sourceLineNo">792</span>      } finally {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>        latch.countDown();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      }<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">796</span><a name="line.796"></a>
+<span class="sourceLineNo">797</span>    /**<a name="line.797"></a>
+<span class="sourceLineNo">798</span>     * @return 1 when the map is not empty.<a name="line.798"></a>
+<span class="sourceLineNo">799</span>     */<a name="line.799"></a>
+<span class="sourceLineNo">800</span>    private int isLogZnodesMapPopulated() {<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      if (sets.size() &gt; 1) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      }<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      if (sets.size() == 1) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        for (String file : files) {<a name="line.807"></a>
+<span class="sourceLineNo">808</span>          // at least one file was missing<a name="line.808"></a>
+<span class="sourceLineNo">809</span>          if (!s.contains(file)) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>            return 0;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>          }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        }<a name="line.812"></a>
+<span class="sourceLineNo">813</span>        return 1; // we found all the files<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      }<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      return 0;<a name="line.815"></a>
+<span class="sourceLineNo">816</span>    }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.819"></a>
 <span class="sourceLineNo">820</span><a name="line.820"></a>
-<span class="sourceLineNo">821</span>    DummyServer(String hostname) {<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      this.hostname = hostname;<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>    @Override<a name="line.825"></a>
-<span class="sourceLineNo">826</span>    public Configuration getConfiguration() {<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      return conf;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    }<a name="line.828"></a>
+<span class="sourceLineNo">821</span>    @Override<a name="line.821"></a>
+<span class="sourceLineNo">822</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.822"></a>
+<span class="sourceLineNo">823</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.823"></a>
+<span class="sourceLineNo">824</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.824"></a>
+<span class="sourceLineNo">825</span>        throws IOException {<a name="line.825"></a>
+<span class="sourceLineNo">826</span>      throw new IOException("Failing deliberately");<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    }<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    @Override<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    public ZKWatcher getZooKeeper() {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      return zkw;<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    }<a name="line.833"></a>
-<span class="sourceLineNo">834</span><a name="line.834"></a>
-<span class="sourceLineNo">835</span>    @Override<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>      return null;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>    }<a name="line.838"></a>
-<span class="sourceLineNo">839</span>    @Override<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    public ClusterConnection getConnection() {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      return null;<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span><a name="line.843"></a>
-<span class="sourceLineNo">844</span>    @Override<a name="line.844"></a>
-<span class="sourceLineNo">845</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.845"></a>
-<span class="sourceLineNo">846</span>      return null;<a name="line.846"></a>
-<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>    @Override<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    public ServerName getServerName() {<a name="line.850"></a>
-<span class="sourceLineNo">851</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    }<a name="line.852"></a>
-<span class="sourceLineNo">853</span><a name="line.853"></a>
-<span class="sourceLineNo">854</span>    @Override<a name="line.854"></a>
-<span class="sourceLineNo">855</span>    public void abort(String why, Throwable e) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    public boolean isAborted() {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      return false;<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>    @Override<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    public void stop(String why) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    }<a name="line.867"></a>
-<span class="sourceLineNo">868</span><a name="line.868"></a>
-<span class="sourceLineNo">869</span>    @Override<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    public boolean isStopped() {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    public ChoreService getChoreService() {<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      return null;<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    }<a name="line.877"></a>
-<span class="sourceLineNo">878</span><a name="line.878"></a>
-<span class="sourceLineNo">879</span>    @Override<a name="line.879"></a>
-<span class="sourceLineNo">880</span>    public ClusterConnection getClusterConnection() {<a name="line.880"></a>
-<span class="sourceLineNo">881</span>      // TODO Auto-generated method stub<a name="line.881"></a>
-<span class="sourceLineNo">882</span>      return null;<a name="line.882"></a>
+<span class="sourceLineNo">830</span>  static class DummyServer implements Server {<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    String hostname;<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>    DummyServer() {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>      hostname = "hostname.example.org";<a name="line.834"></a>
+<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
+<span class="sourceLineNo">836</span><a name="line.836"></a>
+<span class="sourceLineNo">837</span>    DummyServer(String hostname) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      this.hostname = hostname;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>    @Override<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    public Configuration getConfiguration() {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      return conf;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>    }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>    @Override<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    public ZKWatcher getZooKeeper() {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      return zkw;<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span><a name="line.850"></a>
+<span class="sourceLineNo">851</span>    @Override<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>      return null;<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    }<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    @Override<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    public ClusterConnection getConnection() {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      return null;<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>    @Override<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      return null;<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    }<a name="line.863"></a>
+<span class="sourceLineNo">864</span><a name="line.864"></a>
+<span class="sourceLineNo">865</span>    @Override<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    public ServerName getServerName() {<a name="line.866"></a>
+<span class="sourceLineNo">867</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    }<a name="line.868"></a>
+<span class="sourceLineNo">869</span><a name="line.869"></a>
+<span class="sourceLineNo">870</span>    @Override<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    public void abort(String why, Throwable e) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.872"></a>
+<span class="sourceLineNo">873</span>    }<a name="line.873"></a>
+<span class="sourceLineNo">874</span><a name="line.874"></a>
+<span class="sourceLineNo">875</span>    @Override<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    public boolean isAborted() {<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      return false;<a name="line.877"></a>
+<span class="sourceLineNo">878</span>    }<a name="line.878"></a>
+<span class="sourceLineNo">879</span><a name="line.879"></a>
+<span class="sourceLineNo">880</span>    @Override<a name="line.880"></a>
+<span class="sourceLineNo">881</span>    public void stop(String why) {<a name="line.881"></a>
+<span class="sourceLineNo">882</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.882"></a>
 <span class="sourceLineNo">883</span>    }<a name="line.883"></a>
 <span class="sourceLineNo">884</span><a name="line.884"></a>
 <span class="sourceLineNo">885</span>    @Override<a name="line.885"></a>
-<span class="sourceLineNo">886</span>    public FileSystem getFileSystem() {<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return null;<a name="line.887"></a>
+<span class="sourceLineNo">886</span>    public boolean isStopped() {<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    public boolean isStopping() {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      return false;<a name="line.892"></a>
+<span class="sourceLineNo">891</span>    public ChoreService getChoreService() {<a name="line.891"></a>
+<span class="sourceLineNo">892</span>      return null;<a name="line.892"></a>
 <span class="sourceLineNo">893</span>    }<a name="line.893"></a>
 <span class="sourceLineNo">894</span><a name="line.894"></a>
 <span class="sourceLineNo">895</span>    @Override<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.896"></a>
-<span class="sourceLineNo">897</span>      return null;<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">896</span>    public ClusterConnection getClusterConnection() {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // TODO Auto-generated method stub<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      return null;<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>    @Override<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    public FileSystem getFileSystem() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>      return null;<a name="line.903"></a>
+<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>    @Override<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    public boolean isStopping() {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      return false;<a name="line.908"></a>
+<span class="sourceLineNo">909</span>    }<a name="line.909"></a>
+<span class="sourceLineNo">910</span><a name="line.910"></a>
+<span class="sourceLineNo">911</span>    @Override<a name="line.911"></a>
+<span class="sourceLineNo">912</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>      return null;<a name="line.913"></a>
+<span class="sourceLineNo">914</span>    }<a name="line.914"></a>
+<span class="sourceLineNo">915</span>  }<a name="line.915"></a>
+<span class="sourceLineNo">916</span>}<a name="line.916"></a>
 
 
 


[33/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.431"></a>
+<span class="sou

<TRUNCATED>

[34/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadAsRateFunction.html
----------------------------------------------------------------------
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 9d1542c..ec5f688 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
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="li

<TRUNCATED>

[41/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
index 911cf94..557aa17 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
@@ -1081,100 +1081,105 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
+                     byte[]&nbsp;regionName)</code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfoDisplay.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfoDisplay.html#getRegionNameAsStringForDisplay-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.conf.Configuration-">getRegionNameAsStringForDisplay</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
                                org.apache.hadoop.conf.Configuration&nbsp;conf)</code>
 <div class="block">Get the region name for display.</div>
 </td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfoDisplay.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfoDisplay.html#getRegionNameForDisplay-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.conf.Configuration-">getRegionNameForDisplay</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
                        org.apache.hadoop.conf.Configuration&nbsp;conf)</code>
 <div class="block">Get the region name for display.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;hris)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfoDisplay.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfoDisplay.html#getStartKeyForDisplay-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.conf.Configuration-">getStartKeyForDisplay</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri,
                      org.apache.hadoop.conf.Configuration&nbsp;conf)</code>
 <div class="block">Get the start key for display.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionReplicaUtil.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionReplicaUtil.html#isDefaultReplica-org.apache.hadoop.hbase.client.RegionInfo-">isDefaultReplica</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionReplicaUtil.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionReplicaUtil.html#isReplicasForSameRegion-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">isReplicasForSameRegion</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfoA,
                        <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfoB)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">TableSnapshotScanner.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/TableSnapshotScanner.html#isValidRegion-org.apache.hadoop.hbase.client.RegionInfo-">isValidRegion</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">RawAsyncTableImpl.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RawAsyncTableImpl.html#locateFinished-org.apache.hadoop.hbase.client.RegionInfo-byte:A-boolean-">locateFinished</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
               byte[]&nbsp;endKey,
               boolean&nbsp;endKeyInclusive)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.html" title="class in org.apache.hadoop.hbase.client">RegionInfoBuilder</a></code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfoBuilder.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfoBuilder.html#newBuilder-org.apache.hadoop.hbase.client.RegionInfo-">newBuilder</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>(package private) static boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">ConnectionUtils.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/ConnectionUtils.html#noMoreResultsForReverseScan-org.apache.hadoop.hbase.client.Scan-org.apache.hadoop.hbase.client.RegionInfo-">noMoreResultsForReverseScan</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/Scan.html" title="class in org.apache.hadoop.hbase.client">Scan</a>&nbsp;scan,
                            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;info)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) static boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">ConnectionUtils.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/ConnectionUtils.html#noMoreResultsForScan-org.apache.hadoop.hbase.client.Scan-org.apache.hadoop.hbase.client.RegionInfo-">noMoreResultsForScan</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/Scan.html" title="class in org.apache.hadoop.hbase.client">Scan</a>&nbsp;scan,
                     <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;info)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">AsyncTable.CoprocessorCallback.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html#onRegionComplete-org.apache.hadoop.hbase.client.RegionInfo-R-">onRegionComplete</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                 <a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html" title="type parameter in AsyncTable.CoprocessorCallback">R</a>&nbsp;resp)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">AsyncTable.CoprocessorCallback.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/AsyncTable.CoprocessorCallback.html#onRegionError-org.apache.hadoop.hbase.client.RegionInfo-java.lang.Throwable-">onRegionError</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
              <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html?is-external=true" title="class or interface in java.lang">Throwable</a>&nbsp;error)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html?is-external=true" title="class or interface in java.util.concurrent">CompletableFuture</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Void.html?is-external=true" title="class or interface in java.lang">Void</a>&gt;</code></td>
 <td class="colLast"><span class="typeNameLabel">RawAsyncHBaseAdmin.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.html#split-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">split</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri,
      byte[]&nbsp;splitPoint)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html?is-external=true" title="class or interface in java.util.concurrent">Future</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Void.html?is-external=true" title="class or interface in java.lang">Void</a>&gt;</code></td>
 <td class="colLast"><span class="typeNameLabel">HBaseAdmin.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/HBaseAdmin.html#splitRegionAsync-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">splitRegionAsync</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri,
                 byte[]&nbsp;splitPoint)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>...&nbsp;infos)</code>
 <div class="block">Serializes given RegionInfo's as a byte array.</div>
 </td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>static byte[]</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionInfo.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;ri)</code>
 <div class="block">Use this instead of <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-"><code>toByteArray(RegionInfo)</code></a> when writing to a stream and you want to use
  the pb mergeDelimitedFrom (w/o the delimiter, pb reads to EOF which may not be what you want).</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><span class="typeNameLabel">ConnectionImplementation.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/client/ConnectionImplementation.html#updateCachedLocation-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.ServerName-long-">updateCachedLocation</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri,
                     <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;source,

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
index 0a69c99..3110163 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
@@ -555,24 +555,24 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncProcessTask.SubmittedRows.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncProcessTask.SubmittedRows</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.Retry.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncRequestFutureImpl.Retry</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RequestController.ReturnCode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RequestController.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncProcessTask.SubmittedRows.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncProcessTask.SubmittedRows</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/ScannerCallable.MoreResults.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">ScannerCallable.MoreResults</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.Retry.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncRequestFutureImpl.Retry</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
index 7758702..f50799d 100644
--- a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
@@ -183,14 +183,14 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.SatisfiesCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.SatisfiesCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/CompareFilter.CompareOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">CompareFilter.CompareOp</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/BitComparator.BitwiseOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">BitComparator.BitwiseOp</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
index cda2149..10277ab 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -274,11 +274,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.BlockCategory.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType.BlockCategory</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/CacheConfig.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">CacheConfig.ExternalBlockCaches</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/CacheConfig.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">CacheConfig.ExternalBlockCaches</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.BlockCategory.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType.BlockCategory</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/Cacheable.MemoryType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">Cacheable.MemoryType</span></a></li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index df0adf0..7557e4f 100644
--- a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -353,9 +353,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/BufferCallBeforeInitHandler.BufferCallAction.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">BufferCallBeforeInitHandler.BufferCallAction</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
index f1985a3..a1882cb 100644
--- a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
@@ -293,10 +293,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/SyncTable.SyncMapper.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">SyncTable.SyncMapper.Counter</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/RowCounter.RowCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">RowCounter.RowCounterMapper.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
index 4d8d1ce..762fdf7 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html
@@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.LimitedPrivate(value="Configuration")
-public class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.105">StochasticLoadBalancer</a>
+public class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.104">StochasticLoadBalancer</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer</a></pre>
 <div class="block"><p>This is a best effort load balancer. Given a Cost function F(C) =&gt; x It will
  randomly try and mutate the cluster to Cprime. If F(Cprime) &lt; F(C) then the
@@ -671,7 +671,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>STEPS_PER_REGION_KEY</h4>
-<pre>protected 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.html#line.107">STEPS_PER_REGION_KEY</a></pre>
+<pre>protected 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.html#line.106">STEPS_PER_REGION_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.STEPS_PER_REGION_KEY">Constant Field Values</a></dd>
@@ -684,7 +684,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>MAX_STEPS_KEY</h4>
-<pre>protected 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.html#line.109">MAX_STEPS_KEY</a></pre>
+<pre>protected 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.html#line.108">MAX_STEPS_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.MAX_STEPS_KEY">Constant Field Values</a></dd>
@@ -697,7 +697,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>RUN_MAX_STEPS_KEY</h4>
-<pre>protected 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.html#line.111">RUN_MAX_STEPS_KEY</a></pre>
+<pre>protected 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.html#line.110">RUN_MAX_STEPS_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.RUN_MAX_STEPS_KEY">Constant Field Values</a></dd>
@@ -710,7 +710,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>MAX_RUNNING_TIME_KEY</h4>
-<pre>protected 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.html#line.113">MAX_RUNNING_TIME_KEY</a></pre>
+<pre>protected 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.html#line.112">MAX_RUNNING_TIME_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.MAX_RUNNING_TIME_KEY">Constant Field Values</a></dd>
@@ -723,7 +723,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>KEEP_REGION_LOADS</h4>
-<pre>protected 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.html#line.115">KEEP_REGION_LOADS</a></pre>
+<pre>protected 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.html#line.114">KEEP_REGION_LOADS</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.KEEP_REGION_LOADS">Constant Field Values</a></dd>
@@ -736,7 +736,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>TABLE_FUNCTION_SEP</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.html#line.117">TABLE_FUNCTION_SEP</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.html#line.116">TABLE_FUNCTION_SEP</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../../constant-values.html#org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.TABLE_FUNCTION_SEP">Constant Field Values</a></dd>
@@ -749,7 +749,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>MIN_COST_NEED_BALANCE_KEY</h4>
-<pre>protected 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.html#line.118">MIN_COST_NEED_BALANCE_KEY</a></pre>
+<pre>protected 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.html#line.117">MIN_COST_NEED_BALANCE_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.MIN_COST_NEED_BALANCE_KEY">Constant Field Values</a></dd>
@@ -762,7 +762,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>RANDOM</h4>
-<pre>protected static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Random.html?is-external=true" title="class or interface in java.util">Random</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.121">RANDOM</a></pre>
+<pre>protected static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Random.html?is-external=true" title="class or interface in java.util">Random</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.120">RANDOM</a></pre>
 </li>
 </ul>
 <a name="LOG">
@@ -771,7 +771,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.122">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.121">LOG</a></pre>
 </li>
 </ul>
 <a name="loads">
@@ -780,7 +780,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>loads</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&gt;&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.124">loads</a></pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html?is-external=true" title="class or interface in java.util">Deque</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerRegionLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">BalancerRegionLoad</a>&gt;&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.123">loads</a></pre>
 </li>
 </ul>
 <a name="maxSteps">
@@ -789,7 +789,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>maxSteps</h4>
-<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.127">maxSteps</a></pre>
+<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.126">maxSteps</a></pre>
 </li>
 </ul>
 <a name="runMaxSteps">
@@ -798,7 +798,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>runMaxSteps</h4>
-<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.128">runMaxSteps</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.127">runMaxSteps</a></pre>
 </li>
 </ul>
 <a name="stepsPerRegion">
@@ -807,7 +807,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>stepsPerRegion</h4>
-<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.129">stepsPerRegion</a></pre>
+<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.128">stepsPerRegion</a></pre>
 </li>
 </ul>
 <a name="maxRunningTime">
@@ -816,7 +816,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>maxRunningTime</h4>
-<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.130">maxRunningTime</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.129">maxRunningTime</a></pre>
 </li>
 </ul>
 <a name="numRegionLoadsToRemember">
@@ -825,7 +825,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>numRegionLoadsToRemember</h4>
-<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.131">numRegionLoadsToRemember</a></pre>
+<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.130">numRegionLoadsToRemember</a></pre>
 </li>
 </ul>
 <a name="minCostNeedBalance">
@@ -834,7 +834,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>minCostNeedBalance</h4>
-<pre>private&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.132">minCostNeedBalance</a></pre>
+<pre>private&nbsp;float <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.131">minCostNeedBalance</a></pre>
 </li>
 </ul>
 <a name="candidateGenerators">
@@ -843,7 +843,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>candidateGenerators</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/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.134">candidateGenerators</a></pre>
+<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/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.133">candidateGenerators</a></pre>
 </li>
 </ul>
 <a name="regionLoadFunctions">
@@ -852,7 +852,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>regionLoadFunctions</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.135">regionLoadFunctions</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFromRegionLoadFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFromRegionLoadFunction</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.134">regionLoadFunctions</a></pre>
 </li>
 </ul>
 <a name="costFunctions">
@@ -861,7 +861,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>costFunctions</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.136">costFunctions</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CostFunction</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.135">costFunctions</a></pre>
 </li>
 </ul>
 <a name="curOverallCost">
@@ -870,7 +870,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>curOverallCost</h4>
-<pre>private&nbsp;<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> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.139">curOverallCost</a></pre>
+<pre>private&nbsp;<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> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.138">curOverallCost</a></pre>
 </li>
 </ul>
 <a name="tempFunctionCosts">
@@ -879,7 +879,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>tempFunctionCosts</h4>
-<pre>private&nbsp;<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>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.140">tempFunctionCosts</a></pre>
+<pre>private&nbsp;<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>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.139">tempFunctionCosts</a></pre>
 </li>
 </ul>
 <a name="curFunctionCosts">
@@ -888,7 +888,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>curFunctionCosts</h4>
-<pre>private&nbsp;<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>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.141">curFunctionCosts</a></pre>
+<pre>private&nbsp;<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>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.140">curFunctionCosts</a></pre>
 </li>
 </ul>
 <a name="localityCandidateGenerator">
@@ -897,7 +897,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>localityCandidateGenerator</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.LocalityBasedCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.145">localityCandidateGenerator</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.LocalityBasedCandidateGenerator</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.144">localityCandidateGenerator</a></pre>
 </li>
 </ul>
 <a name="localityCost">
@@ -906,7 +906,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>localityCost</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.ServerLocalityCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.146">localityCost</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.ServerLocalityCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.ServerLocalityCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.145">localityCost</a></pre>
 </li>
 </ul>
 <a name="rackLocalityCost">
@@ -915,7 +915,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>rackLocalityCost</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RackLocalityCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.147">rackLocalityCost</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RackLocalityCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RackLocalityCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.146">rackLocalityCost</a></pre>
 </li>
 </ul>
 <a name="regionReplicaHostCostFunction">
@@ -924,7 +924,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>regionReplicaHostCostFunction</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaHostCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.148">regionReplicaHostCostFunction</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaHostCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaHostCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.147">regionReplicaHostCostFunction</a></pre>
 </li>
 </ul>
 <a name="regionReplicaRackCostFunction">
@@ -933,7 +933,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>regionReplicaRackCostFunction</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaRackCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.149">regionReplicaRackCostFunction</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.RegionReplicaRackCostFunction.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.RegionReplicaRackCostFunction</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.148">regionReplicaRackCostFunction</a></pre>
 </li>
 </ul>
 <a name="isByTable">
@@ -942,7 +942,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>isByTable</h4>
-<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.150">isByTable</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.149">isByTable</a></pre>
 </li>
 </ul>
 <a name="tableName">
@@ -951,7 +951,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockListLast">
 <li class="blockList">
 <h4>tableName</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.151">tableName</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.150">tableName</a></pre>
 </li>
 </ul>
 </li>
@@ -968,7 +968,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockListLast">
 <li class="blockList">
 <h4>StochasticLoadBalancer</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.157">StochasticLoadBalancer</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.156">StochasticLoadBalancer</a>()</pre>
 <div class="block">The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its
  default MetricsBalancer</div>
 </li>
@@ -987,7 +987,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>onConfigurationChange</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.162">onConfigurationChange</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.161">onConfigurationChange</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/conf/ConfigurationObserver.html#onConfigurationChange-org.apache.hadoop.conf.Configuration-">ConfigurationObserver</a></code></span></div>
 <div class="block">This method would be called by the <a href="../../../../../../org/apache/hadoop/hbase/conf/ConfigurationManager.html" title="class in org.apache.hadoop.hbase.conf"><code>ConfigurationManager</code></a>
  object when the <code>Configuration</code> object is reloaded from disk.</div>
@@ -1007,7 +1007,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>setConf</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.167">setConf</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.166">setConf</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code>setConf</code>&nbsp;in interface&nbsp;<code>org.apache.hadoop.conf.Configurable</code></dd>
@@ -1022,7 +1022,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>setCandidateGenerators</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.220">setCandidateGenerators</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a>&gt;&nbsp;customCandidateGenerators)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.219">setCandidateGenerators</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.CandidateGenerator.html" title="class in org.apache.hadoop.hbase.master.balancer">StochasticLoadBalancer.CandidateGenerator</a>&gt;&nbsp;customCandidateGenerators)</pre>
 </li>
 </ul>
 <a name="setSlop-org.apache.hadoop.conf.Configuration-">
@@ -1031,7 +1031,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>setSlop</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.225">setSlop</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.224">setSlop</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html#setSlop-org.apache.hadoop.conf.Configuration-">setSlop</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer</a></code></dd>
@@ -1044,7 +1044,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>setClusterMetrics</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.230">setClusterMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a>&nbsp;st)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.229">setClusterMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/ClusterMetrics.html" title="interface in org.apache.hadoop.hbase">ClusterMetrics</a>&nbsp;st)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/LoadBalancer.html#setClusterMetrics-org.apache.hadoop.hbase.ClusterMetrics-">LoadBalancer</a></code></span></div>
 <div class="block">Set the current cluster status.  This allows a LoadBalancer to map host name to a server</div>
 <dl>
@@ -1061,7 +1061,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>updateMetricsSize</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.252">updateMetricsSize</a>(int&nbsp;size)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.251">updateMetricsSize</a>(int&nbsp;size)</pre>
 <div class="block">Update the number of metrics that are reported to JMX</div>
 </li>
 </ul>
@@ -1071,7 +1071,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>setMasterServices</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.259">setMasterServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.258">setMasterServices</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;masterServices)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/LoadBalancer.html#setMasterServices-org.apache.hadoop.hbase.master.MasterServices-">LoadBalancer</a></code></span></div>
 <div class="block">Set the master service.</div>
 <dl>
@@ -1088,7 +1088,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>areSomeRegionReplicasColocated</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.267">areSomeRegionReplicasColocated</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;c)</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.266">areSomeRegionReplicasColocated</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;c)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html#areSomeRegionReplicasColocated-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">BaseLoadBalancer</a></code></span></div>
 <div class="block">Subclasses should implement this to return true if the cluster has nodes that hosts
  multiple replicas for the same region, or, if there are multiple racks and the same
@@ -1109,7 +1109,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseL
 <ul class="blockList">
 <li class="blockList">
 <h4>needsBalance</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.276">needsBalance</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;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.275">needsBalance</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>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html#needsBalance-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">needsBalance</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.html" title="class in org.apache.hadoop.hbase.master.balancer">BaseLoadBalancer</a></code></dd>
@@ -1122,7 +1122,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.317">balanceCluster</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<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.316">balanceCluster</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/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&gt;&nbsp;clusterState)</pre>
 <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>
@@ -1138,7 +1138,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.324">nextAction</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><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.323">nextAction</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="balanceCluster-java.util.Map-">
@@ -1147,7 +1147,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.334">balanceCluster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&gt;&nbsp;
 clusterState)</pre>
+<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.333">balanceCluster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&gt;&nbsp;
 clusterState)</pre>
 <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>
@@ -1162,7 +1162,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.460">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.459">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>
@@ -1174,7 +1174,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.482">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.481">functionCost</a>()</pre>
 </li>
 </ul>
 <a name="createRegionPlans-org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster-">
@@ -1183,7 +1183,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.502">createRegionPlans</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>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.501">createRegionPlans</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">Create all of the RegionPlan's needed to move from the initial cluster state to the desired
  state.</div>
 <dl>
@@ -1200,7 +1200,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.528">updateRegionLoad</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html#line.527">updateRegionLoad</a>()</pre>
 <div class="block">Store the current region loads.</div>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
index cd81f5c..b995fc1 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
@@ -349,8 +349,8 @@
 <ul>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MetricsMasterSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MetricsMasterSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
 </ul>
 </li>


[04/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
index 006d1ba..18cf507 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/replication/regionserver/TestReplicationSourceManager.DummyNodeFailoverWorker.html
@@ -654,258 +654,274 @@
 <span class="sourceLineNo">646</span>    }<a name="line.646"></a>
 <span class="sourceLineNo">647</span>  }<a name="line.647"></a>
 <span class="sourceLineNo">648</span><a name="line.648"></a>
-<span class="sourceLineNo">649</span>  /**<a name="line.649"></a>
-<span class="sourceLineNo">650</span>   * Add a peer and wait for it to initialize<a name="line.650"></a>
-<span class="sourceLineNo">651</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.651"></a>
-<span class="sourceLineNo">652</span>   */<a name="line.652"></a>
-<span class="sourceLineNo">653</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.653"></a>
-<span class="sourceLineNo">654</span>      final boolean waitForSource) throws Exception {<a name="line.654"></a>
-<span class="sourceLineNo">655</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.655"></a>
-<span class="sourceLineNo">656</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.656"></a>
-<span class="sourceLineNo">657</span>    try {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>      manager.addPeer(peerId);<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    } catch (Exception e) {<a name="line.659"></a>
-<span class="sourceLineNo">660</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    }<a name="line.661"></a>
-<span class="sourceLineNo">662</span>    waitPeer(peerId, manager, waitForSource);<a name="line.662"></a>
-<span class="sourceLineNo">663</span>    if (managerOfCluster != null) {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      managerOfCluster.addPeer(peerId);<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    }<a name="line.666"></a>
-<span class="sourceLineNo">667</span>  }<a name="line.667"></a>
-<span class="sourceLineNo">668</span><a name="line.668"></a>
-<span class="sourceLineNo">669</span>  private static void waitPeer(final String peerId,<a name="line.669"></a>
-<span class="sourceLineNo">670</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.672"></a>
-<span class="sourceLineNo">673</span>      if (waitForSource) {<a name="line.673"></a>
-<span class="sourceLineNo">674</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>        if (rs == null) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          return false;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>        }<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.678"></a>
-<span class="sourceLineNo">679</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.679"></a>
-<span class="sourceLineNo">680</span>        }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>        return true;<a name="line.681"></a>
-<span class="sourceLineNo">682</span>      } else {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>        return (rp.getPeer(peerId) != null);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>      }<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    });<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>  /**<a name="line.688"></a>
-<span class="sourceLineNo">689</span>   * Remove a peer and wait for it to get cleaned up<a name="line.689"></a>
-<span class="sourceLineNo">690</span>   * @param peerId<a name="line.690"></a>
-<span class="sourceLineNo">691</span>   * @throws Exception<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      try {<a name="line.697"></a>
-<span class="sourceLineNo">698</span>        manager.removePeer(peerId);<a name="line.698"></a>
-<span class="sourceLineNo">699</span>      } catch (Exception e) {<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        // ignore the failed exception and continue.<a name="line.700"></a>
-<span class="sourceLineNo">701</span>      }<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>      @Override<a name="line.704"></a>
-<span class="sourceLineNo">705</span>      public boolean evaluate() throws Exception {<a name="line.705"></a>
-<span class="sourceLineNo">706</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.706"></a>
-<span class="sourceLineNo">707</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<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>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.713"></a>
-<span class="sourceLineNo">714</span>    // 1. Create store files for the families<a name="line.714"></a>
-<span class="sourceLineNo">715</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.718"></a>
-<span class="sourceLineNo">719</span>    p.add(hfilePath1);<a name="line.719"></a>
-<span class="sourceLineNo">720</span>    try {<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.721"></a>
-<span class="sourceLineNo">722</span>    } catch (IOException e) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    }<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    storeFiles.put(f1, p);<a name="line.726"></a>
-<span class="sourceLineNo">727</span>    scope.put(f1, 1);<a name="line.727"></a>
-<span class="sourceLineNo">728</span>    p = new ArrayList&lt;&gt;(1);<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.729"></a>
-<span class="sourceLineNo">730</span>    p.add(hfilePath2);<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    try {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    } catch (IOException e) {<a name="line.733"></a>
-<span class="sourceLineNo">734</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    }<a name="line.736"></a>
-<span class="sourceLineNo">737</span>    storeFiles.put(f2, p);<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    // 2. Create bulk load descriptor<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    BulkLoadDescriptor desc =<a name="line.739"></a>
-<span class="sourceLineNo">740</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.740"></a>
-<span class="sourceLineNo">741</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.741"></a>
-<span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    // 3. create bulk load wal edit event<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    return logEdit;<a name="line.745"></a>
-<span class="sourceLineNo">746</span>  }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>  static class DummyNodeFailoverWorker extends Thread {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    Server server;<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    private ServerName deadRS;<a name="line.751"></a>
-<span class="sourceLineNo">752</span>    ReplicationQueueStorage rq;<a name="line.752"></a>
-<span class="sourceLineNo">753</span><a name="line.753"></a>
-<span class="sourceLineNo">754</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      this.deadRS = deadRS;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>      this.server = s;<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.757"></a>
-<span class="sourceLineNo">758</span>        server.getConfiguration());<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>    @Override<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    public void run() {<a name="line.762"></a>
-<span class="sourceLineNo">763</span>      try {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.764"></a>
-<span class="sourceLineNo">765</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>        for (String queue : queues) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.767"></a>
-<span class="sourceLineNo">768</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.768"></a>
-<span class="sourceLineNo">769</span>          if (pair != null) {<a name="line.769"></a>
-<span class="sourceLineNo">770</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>      } catch (Exception e) {<a name="line.774"></a>
-<span class="sourceLineNo">775</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      } finally {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>        latch.countDown();<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      }<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    /**<a name="line.781"></a>
-<span class="sourceLineNo">782</span>     * @return 1 when the map is not empty.<a name="line.782"></a>
-<span class="sourceLineNo">783</span>     */<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    private int isLogZnodesMapPopulated() {<a name="line.784"></a>
-<span class="sourceLineNo">785</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.785"></a>
-<span class="sourceLineNo">786</span>      if (sets.size() &gt; 1) {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      }<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (sets.size() == 1) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.790"></a>
-<span class="sourceLineNo">791</span>        for (String file : files) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>          // at least one file was missing<a name="line.792"></a>
-<span class="sourceLineNo">793</span>          if (!s.contains(file)) {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>            return 0;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>          }<a name="line.795"></a>
-<span class="sourceLineNo">796</span>        }<a name="line.796"></a>
-<span class="sourceLineNo">797</span>        return 1; // we found all the files<a name="line.797"></a>
-<span class="sourceLineNo">798</span>      }<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return 0;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span><a name="line.802"></a>
-<span class="sourceLineNo">803</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.803"></a>
-<span class="sourceLineNo">804</span><a name="line.804"></a>
-<span class="sourceLineNo">805</span>    @Override<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.806"></a>
-<span class="sourceLineNo">807</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.807"></a>
-<span class="sourceLineNo">808</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.808"></a>
-<span class="sourceLineNo">809</span>        throws IOException {<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      throw new IOException("Failing deliberately");<a name="line.810"></a>
-<span class="sourceLineNo">811</span>    }<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>  static class DummyServer implements Server {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    String hostname;<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>    DummyServer() {<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      hostname = "hostname.example.org";<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    }<a name="line.819"></a>
+<span class="sourceLineNo">649</span>  @Test<a name="line.649"></a>
+<span class="sourceLineNo">650</span>  public void testSameWALPrefix() throws IOException {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    Set&lt;String&gt; latestWalsBefore =<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      manager.getLastestPath().stream().map(Path::getName).collect(Collectors.toSet());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    String walName1 = "localhost,8080,12345-45678-Peer.34567";<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    String walName2 = "localhost,8080,12345.56789";<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    manager.preLogRoll(new Path(walName1));<a name="line.655"></a>
+<span class="sourceLineNo">656</span>    manager.preLogRoll(new Path(walName2));<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>    Set&lt;String&gt; latestWals = manager.getLastestPath().stream().map(Path::getName)<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      .filter(n -&gt; !latestWalsBefore.contains(n)).collect(Collectors.toSet());<a name="line.659"></a>
+<span class="sourceLineNo">660</span>    assertEquals(2, latestWals.size());<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    assertTrue(latestWals.contains(walName1));<a name="line.661"></a>
+<span class="sourceLineNo">662</span>    assertTrue(latestWals.contains(walName2));<a name="line.662"></a>
+<span class="sourceLineNo">663</span>  }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>  /**<a name="line.665"></a>
+<span class="sourceLineNo">666</span>   * Add a peer and wait for it to initialize<a name="line.666"></a>
+<span class="sourceLineNo">667</span>   * @param waitForSource Whether to wait for replication source to initialize<a name="line.667"></a>
+<span class="sourceLineNo">668</span>   */<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  private void addPeerAndWait(final String peerId, final ReplicationPeerConfig peerConfig,<a name="line.669"></a>
+<span class="sourceLineNo">670</span>      final boolean waitForSource) throws Exception {<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    rp.getPeerStorage().addPeer(peerId, peerConfig, true, SyncReplicationState.NONE);<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    try {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      manager.addPeer(peerId);<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    } catch (Exception e) {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      // ignore the failed exception, because we'll test both success &amp; failed case.<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    waitPeer(peerId, manager, waitForSource);<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    if (managerOfCluster != null) {<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      managerOfCluster.addPeer(peerId);<a name="line.680"></a>
+<span class="sourceLineNo">681</span>      waitPeer(peerId, managerOfCluster, waitForSource);<a name="line.681"></a>
+<span class="sourceLineNo">682</span>    }<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>  private static void waitPeer(final String peerId,<a name="line.685"></a>
+<span class="sourceLineNo">686</span>      ReplicationSourceManager manager, final boolean waitForSource) {<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ReplicationPeers rp = manager.getReplicationPeers();<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    Waiter.waitFor(conf, 20000, () -&gt; {<a name="line.688"></a>
+<span class="sourceLineNo">689</span>      if (waitForSource) {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>        ReplicationSourceInterface rs = manager.getSource(peerId);<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        if (rs == null) {<a name="line.691"></a>
+<span class="sourceLineNo">692</span>          return false;<a name="line.692"></a>
+<span class="sourceLineNo">693</span>        }<a name="line.693"></a>
+<span class="sourceLineNo">694</span>        if (rs instanceof ReplicationSourceDummy) {<a name="line.694"></a>
+<span class="sourceLineNo">695</span>          return ((ReplicationSourceDummy)rs).isStartup();<a name="line.695"></a>
+<span class="sourceLineNo">696</span>        }<a name="line.696"></a>
+<span class="sourceLineNo">697</span>        return true;<a name="line.697"></a>
+<span class="sourceLineNo">698</span>      } else {<a name="line.698"></a>
+<span class="sourceLineNo">699</span>        return (rp.getPeer(peerId) != null);<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      }<a name="line.700"></a>
+<span class="sourceLineNo">701</span>    });<a name="line.701"></a>
+<span class="sourceLineNo">702</span>  }<a name="line.702"></a>
+<span class="sourceLineNo">703</span><a name="line.703"></a>
+<span class="sourceLineNo">704</span>  /**<a name="line.704"></a>
+<span class="sourceLineNo">705</span>   * Remove a peer and wait for it to get cleaned up<a name="line.705"></a>
+<span class="sourceLineNo">706</span>   * @param peerId<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * @throws Exception<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   */<a name="line.708"></a>
+<span class="sourceLineNo">709</span>  private void removePeerAndWait(final String peerId) throws Exception {<a name="line.709"></a>
+<span class="sourceLineNo">710</span>    final ReplicationPeers rp = manager.getReplicationPeers();<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    if (rp.getPeerStorage().listPeerIds().contains(peerId)) {<a name="line.711"></a>
+<span class="sourceLineNo">712</span>      rp.getPeerStorage().removePeer(peerId);<a name="line.712"></a>
+<span class="sourceLineNo">713</span>      try {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>        manager.removePeer(peerId);<a name="line.714"></a>
+<span class="sourceLineNo">715</span>      } catch (Exception e) {<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        // ignore the failed exception and continue.<a name="line.716"></a>
+<span class="sourceLineNo">717</span>      }<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    }<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    Waiter.waitFor(conf, 20000, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      @Override<a name="line.720"></a>
+<span class="sourceLineNo">721</span>      public boolean evaluate() throws Exception {<a name="line.721"></a>
+<span class="sourceLineNo">722</span>        Collection&lt;String&gt; peers = rp.getPeerStorage().listPeerIds();<a name="line.722"></a>
+<span class="sourceLineNo">723</span>        return (!manager.getAllQueues().contains(peerId)) &amp;&amp; (rp.getPeer(peerId) == null)<a name="line.723"></a>
+<span class="sourceLineNo">724</span>            &amp;&amp; (!peers.contains(peerId)) &amp;&amp; manager.getSource(peerId) == null;<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      }<a name="line.725"></a>
+<span class="sourceLineNo">726</span>    });<a name="line.726"></a>
+<span class="sourceLineNo">727</span>  }<a name="line.727"></a>
+<span class="sourceLineNo">728</span><a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private WALEdit getBulkLoadWALEdit(NavigableMap&lt;byte[], Integer&gt; scope) {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    // 1. Create store files for the families<a name="line.730"></a>
+<span class="sourceLineNo">731</span>    Map&lt;byte[], List&lt;Path&gt;&gt; storeFiles = new HashMap&lt;&gt;(1);<a name="line.731"></a>
+<span class="sourceLineNo">732</span>    Map&lt;String, Long&gt; storeFilesSize = new HashMap&lt;&gt;(1);<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    List&lt;Path&gt; p = new ArrayList&lt;&gt;(1);<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    Path hfilePath1 = new Path(Bytes.toString(f1));<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    p.add(hfilePath1);<a name="line.735"></a>
+<span class="sourceLineNo">736</span>    try {<a name="line.736"></a>
+<span class="sourceLineNo">737</span>      storeFilesSize.put(hfilePath1.getName(), fs.getFileStatus(hfilePath1).getLen());<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    } catch (IOException e) {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath1);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>      storeFilesSize.put(hfilePath1.getName(), 0L);<a name="line.740"></a>
+<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>    storeFiles.put(f1, p);<a name="line.742"></a>
+<span class="sourceLineNo">743</span>    scope.put(f1, 1);<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    p = new ArrayList&lt;&gt;(1);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    Path hfilePath2 = new Path(Bytes.toString(f2));<a name="line.745"></a>
+<span class="sourceLineNo">746</span>    p.add(hfilePath2);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    try {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>      storeFilesSize.put(hfilePath2.getName(), fs.getFileStatus(hfilePath2).getLen());<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    } catch (IOException e) {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>      LOG.debug("Failed to calculate the size of hfile " + hfilePath2);<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      storeFilesSize.put(hfilePath2.getName(), 0L);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    }<a name="line.752"></a>
+<span class="sourceLineNo">753</span>    storeFiles.put(f2, p);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // 2. Create bulk load descriptor<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    BulkLoadDescriptor desc =<a name="line.755"></a>
+<span class="sourceLineNo">756</span>        ProtobufUtil.toBulkLoadDescriptor(hri.getTable(),<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes()), storeFiles, storeFilesSize, 1);<a name="line.757"></a>
+<span class="sourceLineNo">758</span><a name="line.758"></a>
+<span class="sourceLineNo">759</span>    // 3. create bulk load wal edit event<a name="line.759"></a>
+<span class="sourceLineNo">760</span>    WALEdit logEdit = WALEdit.createBulkLoadEvent(hri, desc);<a name="line.760"></a>
+<span class="sourceLineNo">761</span>    return logEdit;<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>  static class DummyNodeFailoverWorker extends Thread {<a name="line.764"></a>
+<span class="sourceLineNo">765</span>    private Map&lt;String, Set&lt;String&gt;&gt; logZnodesMap;<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    Server server;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    private ServerName deadRS;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    ReplicationQueueStorage rq;<a name="line.768"></a>
+<span class="sourceLineNo">769</span><a name="line.769"></a>
+<span class="sourceLineNo">770</span>    public DummyNodeFailoverWorker(ServerName deadRS, Server s) throws Exception {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      this.deadRS = deadRS;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>      this.server = s;<a name="line.772"></a>
+<span class="sourceLineNo">773</span>      this.rq = ReplicationStorageFactory.getReplicationQueueStorage(server.getZooKeeper(),<a name="line.773"></a>
+<span class="sourceLineNo">774</span>        server.getConfiguration());<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    }<a name="line.775"></a>
+<span class="sourceLineNo">776</span><a name="line.776"></a>
+<span class="sourceLineNo">777</span>    @Override<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    public void run() {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>      try {<a name="line.779"></a>
+<span class="sourceLineNo">780</span>        logZnodesMap = new HashMap&lt;&gt;();<a name="line.780"></a>
+<span class="sourceLineNo">781</span>        List&lt;String&gt; queues = rq.getAllQueues(deadRS);<a name="line.781"></a>
+<span class="sourceLineNo">782</span>        for (String queue : queues) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>          Pair&lt;String, SortedSet&lt;String&gt;&gt; pair =<a name="line.783"></a>
+<span class="sourceLineNo">784</span>              rq.claimQueue(deadRS, queue, server.getServerName());<a name="line.784"></a>
+<span class="sourceLineNo">785</span>          if (pair != null) {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>            logZnodesMap.put(pair.getFirst(), pair.getSecond());<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>        server.abort("Done with testing", null);<a name="line.789"></a>
+<span class="sourceLineNo">790</span>      } catch (Exception e) {<a name="line.790"></a>
+<span class="sourceLineNo">791</span>        LOG.error("Got exception while running NodeFailoverWorker", e);<a name="line.791"></a>
+<span class="sourceLineNo">792</span>      } finally {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>        latch.countDown();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>      }<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">796</span><a name="line.796"></a>
+<span class="sourceLineNo">797</span>    /**<a name="line.797"></a>
+<span class="sourceLineNo">798</span>     * @return 1 when the map is not empty.<a name="line.798"></a>
+<span class="sourceLineNo">799</span>     */<a name="line.799"></a>
+<span class="sourceLineNo">800</span>    private int isLogZnodesMapPopulated() {<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      Collection&lt;Set&lt;String&gt;&gt; sets = logZnodesMap.values();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      if (sets.size() &gt; 1) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>        throw new RuntimeException("unexpected size of logZnodesMap: " + sets.size());<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      }<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      if (sets.size() == 1) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        Set&lt;String&gt; s = sets.iterator().next();<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        for (String file : files) {<a name="line.807"></a>
+<span class="sourceLineNo">808</span>          // at least one file was missing<a name="line.808"></a>
+<span class="sourceLineNo">809</span>          if (!s.contains(file)) {<a name="line.809"></a>
+<span class="sourceLineNo">810</span>            return 0;<a name="line.810"></a>
+<span class="sourceLineNo">811</span>          }<a name="line.811"></a>
+<span class="sourceLineNo">812</span>        }<a name="line.812"></a>
+<span class="sourceLineNo">813</span>        return 1; // we found all the files<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      }<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      return 0;<a name="line.815"></a>
+<span class="sourceLineNo">816</span>    }<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  static class FailInitializeDummyReplicationSource extends ReplicationSourceDummy {<a name="line.819"></a>
 <span class="sourceLineNo">820</span><a name="line.820"></a>
-<span class="sourceLineNo">821</span>    DummyServer(String hostname) {<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      this.hostname = hostname;<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>    @Override<a name="line.825"></a>
-<span class="sourceLineNo">826</span>    public Configuration getConfiguration() {<a name="line.826"></a>
-<span class="sourceLineNo">827</span>      return conf;<a name="line.827"></a>
-<span class="sourceLineNo">828</span>    }<a name="line.828"></a>
+<span class="sourceLineNo">821</span>    @Override<a name="line.821"></a>
+<span class="sourceLineNo">822</span>    public void init(Configuration conf, FileSystem fs, ReplicationSourceManager manager,<a name="line.822"></a>
+<span class="sourceLineNo">823</span>        ReplicationQueueStorage rq, ReplicationPeer rp, Server server, String peerClusterId,<a name="line.823"></a>
+<span class="sourceLineNo">824</span>        UUID clusterId, WALFileLengthProvider walFileLengthProvider, MetricsSource metrics)<a name="line.824"></a>
+<span class="sourceLineNo">825</span>        throws IOException {<a name="line.825"></a>
+<span class="sourceLineNo">826</span>      throw new IOException("Failing deliberately");<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    }<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
 <span class="sourceLineNo">829</span><a name="line.829"></a>
-<span class="sourceLineNo">830</span>    @Override<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    public ZKWatcher getZooKeeper() {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      return zkw;<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    }<a name="line.833"></a>
-<span class="sourceLineNo">834</span><a name="line.834"></a>
-<span class="sourceLineNo">835</span>    @Override<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>      return null;<a name="line.837"></a>
-<span class="sourceLineNo">838</span>    }<a name="line.838"></a>
-<span class="sourceLineNo">839</span>    @Override<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    public ClusterConnection getConnection() {<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      return null;<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span><a name="line.843"></a>
-<span class="sourceLineNo">844</span>    @Override<a name="line.844"></a>
-<span class="sourceLineNo">845</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.845"></a>
-<span class="sourceLineNo">846</span>      return null;<a name="line.846"></a>
-<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
-<span class="sourceLineNo">848</span><a name="line.848"></a>
-<span class="sourceLineNo">849</span>    @Override<a name="line.849"></a>
-<span class="sourceLineNo">850</span>    public ServerName getServerName() {<a name="line.850"></a>
-<span class="sourceLineNo">851</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    }<a name="line.852"></a>
-<span class="sourceLineNo">853</span><a name="line.853"></a>
-<span class="sourceLineNo">854</span>    @Override<a name="line.854"></a>
-<span class="sourceLineNo">855</span>    public void abort(String why, Throwable e) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    public boolean isAborted() {<a name="line.860"></a>
-<span class="sourceLineNo">861</span>      return false;<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>    @Override<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    public void stop(String why) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.866"></a>
-<span class="sourceLineNo">867</span>    }<a name="line.867"></a>
-<span class="sourceLineNo">868</span><a name="line.868"></a>
-<span class="sourceLineNo">869</span>    @Override<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    public boolean isStopped() {<a name="line.870"></a>
-<span class="sourceLineNo">871</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.874"></a>
-<span class="sourceLineNo">875</span>    public ChoreService getChoreService() {<a name="line.875"></a>
-<span class="sourceLineNo">876</span>      return null;<a name="line.876"></a>
-<span class="sourceLineNo">877</span>    }<a name="line.877"></a>
-<span class="sourceLineNo">878</span><a name="line.878"></a>
-<span class="sourceLineNo">879</span>    @Override<a name="line.879"></a>
-<span class="sourceLineNo">880</span>    public ClusterConnection getClusterConnection() {<a name="line.880"></a>
-<span class="sourceLineNo">881</span>      // TODO Auto-generated method stub<a name="line.881"></a>
-<span class="sourceLineNo">882</span>      return null;<a name="line.882"></a>
+<span class="sourceLineNo">830</span>  static class DummyServer implements Server {<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    String hostname;<a name="line.831"></a>
+<span class="sourceLineNo">832</span><a name="line.832"></a>
+<span class="sourceLineNo">833</span>    DummyServer() {<a name="line.833"></a>
+<span class="sourceLineNo">834</span>      hostname = "hostname.example.org";<a name="line.834"></a>
+<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
+<span class="sourceLineNo">836</span><a name="line.836"></a>
+<span class="sourceLineNo">837</span>    DummyServer(String hostname) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      this.hostname = hostname;<a name="line.838"></a>
+<span class="sourceLineNo">839</span>    }<a name="line.839"></a>
+<span class="sourceLineNo">840</span><a name="line.840"></a>
+<span class="sourceLineNo">841</span>    @Override<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    public Configuration getConfiguration() {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>      return conf;<a name="line.843"></a>
+<span class="sourceLineNo">844</span>    }<a name="line.844"></a>
+<span class="sourceLineNo">845</span><a name="line.845"></a>
+<span class="sourceLineNo">846</span>    @Override<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    public ZKWatcher getZooKeeper() {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      return zkw;<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span><a name="line.850"></a>
+<span class="sourceLineNo">851</span>    @Override<a name="line.851"></a>
+<span class="sourceLineNo">852</span>    public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>      return null;<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    }<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    @Override<a name="line.855"></a>
+<span class="sourceLineNo">856</span>    public ClusterConnection getConnection() {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>      return null;<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>    @Override<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    public MetaTableLocator getMetaTableLocator() {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      return null;<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    }<a name="line.863"></a>
+<span class="sourceLineNo">864</span><a name="line.864"></a>
+<span class="sourceLineNo">865</span>    @Override<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    public ServerName getServerName() {<a name="line.866"></a>
+<span class="sourceLineNo">867</span>      return ServerName.valueOf(hostname, 1234, 1L);<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    }<a name="line.868"></a>
+<span class="sourceLineNo">869</span><a name="line.869"></a>
+<span class="sourceLineNo">870</span>    @Override<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    public void abort(String why, Throwable e) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.872"></a>
+<span class="sourceLineNo">873</span>    }<a name="line.873"></a>
+<span class="sourceLineNo">874</span><a name="line.874"></a>
+<span class="sourceLineNo">875</span>    @Override<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    public boolean isAborted() {<a name="line.876"></a>
+<span class="sourceLineNo">877</span>      return false;<a name="line.877"></a>
+<span class="sourceLineNo">878</span>    }<a name="line.878"></a>
+<span class="sourceLineNo">879</span><a name="line.879"></a>
+<span class="sourceLineNo">880</span>    @Override<a name="line.880"></a>
+<span class="sourceLineNo">881</span>    public void stop(String why) {<a name="line.881"></a>
+<span class="sourceLineNo">882</span>      // To change body of implemented methods use File | Settings | File Templates.<a name="line.882"></a>
 <span class="sourceLineNo">883</span>    }<a name="line.883"></a>
 <span class="sourceLineNo">884</span><a name="line.884"></a>
 <span class="sourceLineNo">885</span>    @Override<a name="line.885"></a>
-<span class="sourceLineNo">886</span>    public FileSystem getFileSystem() {<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      return null;<a name="line.887"></a>
+<span class="sourceLineNo">886</span>    public boolean isStopped() {<a name="line.886"></a>
+<span class="sourceLineNo">887</span>      return false; // To change body of implemented methods use File | Settings | File Templates.<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>    @Override<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    public boolean isStopping() {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      return false;<a name="line.892"></a>
+<span class="sourceLineNo">891</span>    public ChoreService getChoreService() {<a name="line.891"></a>
+<span class="sourceLineNo">892</span>      return null;<a name="line.892"></a>
 <span class="sourceLineNo">893</span>    }<a name="line.893"></a>
 <span class="sourceLineNo">894</span><a name="line.894"></a>
 <span class="sourceLineNo">895</span>    @Override<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.896"></a>
-<span class="sourceLineNo">897</span>      return null;<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">896</span>    public ClusterConnection getClusterConnection() {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // TODO Auto-generated method stub<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      return null;<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>    @Override<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    public FileSystem getFileSystem() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>      return null;<a name="line.903"></a>
+<span class="sourceLineNo">904</span>    }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>    @Override<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    public boolean isStopping() {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      return false;<a name="line.908"></a>
+<span class="sourceLineNo">909</span>    }<a name="line.909"></a>
+<span class="sourceLineNo">910</span><a name="line.910"></a>
+<span class="sourceLineNo">911</span>    @Override<a name="line.911"></a>
+<span class="sourceLineNo">912</span>    public Connection createConnection(Configuration conf) throws IOException {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>      return null;<a name="line.913"></a>
+<span class="sourceLineNo">914</span>    }<a name="line.914"></a>
+<span class="sourceLineNo">915</span>  }<a name="line.915"></a>
+<span class="sourceLineNo">916</span>}<a name="line.916"></a>
 
 
 


[39/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
index 576c53f..42fb6ff 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10,"i38":10,"i39":10,"i40":10};
+var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10,"i38":10,"i39":10,"i40":10,"i41":10};
 var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -222,7 +222,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#fs">fs</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
-<td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;org.apache.hadoop.fs.Path&gt;</code></td>
+<td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,org.apache.hadoop.fs.Path&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#latestPaths">latestPaths</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
@@ -432,116 +432,120 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 </td>
 </tr>
 <tr id="i16" class="altColor">
+<td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;org.apache.hadoop.fs.Path&gt;</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getLastestPath--">getLastestPath</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i17" class="rowColor">
 <td class="colFirst"><code>org.apache.hadoop.fs.Path</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getLogDir--">getLogDir</a></span>()</code>
 <div class="block">Get the directory where wals are stored by their RSs</div>
 </td>
 </tr>
-<tr id="i17" class="rowColor">
+<tr id="i18" class="altColor">
 <td class="colFirst"><code>org.apache.hadoop.fs.Path</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getOldLogDir--">getOldLogDir</a></span>()</code>
 <div class="block">Get the directory where wals are archived</div>
 </td>
 </tr>
-<tr id="i18" class="altColor">
+<tr id="i19" class="rowColor">
 <td class="colFirst"><code><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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getOldSources--">getOldSources</a></span>()</code>
 <div class="block">Get a list of all the recovered sources of this rs</div>
 </td>
 </tr>
-<tr id="i19" class="rowColor">
+<tr id="i20" class="altColor">
 <td class="colFirst"><code><a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeers.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeers</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getReplicationPeers--">getReplicationPeers</a></span>()</code>
 <div class="block">Get the ReplicationPeers used by this ReplicationSourceManager</div>
 </td>
 </tr>
-<tr id="i20" class="altColor">
+<tr id="i21" class="rowColor">
 <td class="colFirst"><code>(package private) int</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getSizeOfLatestPath--">getSizeOfLatestPath</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i21" class="rowColor">
+<tr id="i22" class="altColor">
 <td class="colFirst"><code><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getSource-java.lang.String-">getSource</a></span>(<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;peerId)</code>
 <div class="block">Get the normal source for a given peer</div>
 </td>
 </tr>
-<tr id="i22" class="altColor">
+<tr id="i23" class="rowColor">
 <td class="colFirst"><code><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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getSources--">getSources</a></span>()</code>
 <div class="block">Get a list of all the normal sources of this rs</div>
 </td>
 </tr>
-<tr id="i23" class="rowColor">
+<tr id="i24" class="altColor">
 <td class="colFirst"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getStats--">getStats</a></span>()</code>
 <div class="block">Get a string representation of all the sources' metrics</div>
 </td>
 </tr>
-<tr id="i24" class="altColor">
+<tr id="i25" class="rowColor">
 <td class="colFirst"><code><a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicLong.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicLong</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getTotalBufferUsed--">getTotalBufferUsed</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i25" class="rowColor">
+<tr id="i26" class="altColor">
 <td class="colFirst"><code><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/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getWALs--">getWALs</a></span>()</code>
 <div class="block">Get a copy of the wals of the normal sources on this rs</div>
 </td>
 </tr>
-<tr id="i26" class="altColor">
+<tr id="i27" class="rowColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#getWalsByIdRecoveredQueues--">getWalsByIdRecoveredQueues</a></span>()</code>
 <div class="block">Get a copy of the wals of the recovered sources on this rs</div>
 </td>
 </tr>
-<tr id="i27" class="rowColor">
+<tr id="i28" class="altColor">
 <td class="colFirst"><code>(package private) <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html?is-external=true" title="class or interface in java.util.concurrent">Future</a>&lt;?&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#init--">init</a></span>()</code>
 <div class="block">Adds a normal source per registered peer cluster and tries to process all old region server wal
  queues</div>
 </td>
 </tr>
-<tr id="i28" class="altColor">
+<tr id="i29" class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#interruptOrAbortWhenFail-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager.ReplicationQueueOperation-">interruptOrAbortWhenFail</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</code>
 <div class="block">Refresh replication source will terminate the old source first, then the source thread will be
  interrupted.</div>
 </td>
 </tr>
-<tr id="i29" class="rowColor">
+<tr id="i30" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#join--">join</a></span>()</code>
 <div class="block">Terminate the replication on this region server</div>
 </td>
 </tr>
-<tr id="i30" class="altColor">
+<tr id="i31" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#logPositionAndCleanOldLogs-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceInterface-org.apache.hadoop.hbase.replication.regionserver.WALEntryBatch-">logPositionAndCleanOldLogs</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;source,
                           <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/WALEntryBatch.html" title="class in org.apache.hadoop.hbase.replication.regionserver">WALEntryBatch</a>&nbsp;entryBatch)</code>
 <div class="block">This method will log the current position to storage.</div>
 </td>
 </tr>
-<tr id="i31" class="rowColor">
+<tr id="i32" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#postLogRoll-org.apache.hadoop.fs.Path-">postLogRoll</a></span>(org.apache.hadoop.fs.Path&nbsp;newLog)</code>&nbsp;</td>
 </tr>
-<tr id="i32" class="altColor">
+<tr id="i33" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#preLogRoll-org.apache.hadoop.fs.Path-">preLogRoll</a></span>(org.apache.hadoop.fs.Path&nbsp;newLog)</code>&nbsp;</td>
 </tr>
-<tr id="i33" class="rowColor">
+<tr id="i34" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#refreshSources-java.lang.String-">refreshSources</a></span>(<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;peerId)</code>
 <div class="block">Close the previous replication sources of this peer id and open new sources to trigger the new
  replication state changes or new replication config changes.</div>
 </td>
 </tr>
-<tr id="i34" class="altColor">
+<tr id="i35" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#regionServerRemoved-java.lang.String-">regionServerRemoved</a></span>(<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;regionserver)</code>
 <div class="block">A region server has been removed from the local cluster</div>
 </td>
 </tr>
-<tr id="i35" class="rowColor">
+<tr id="i36" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#removePeer-java.lang.String-">removePeer</a></span>(<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;peerId)</code>
 <div class="block">
@@ -552,29 +556,29 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
  </div>
 </td>
 </tr>
-<tr id="i36" class="altColor">
+<tr id="i37" class="rowColor">
 <td class="colFirst"><code>private boolean</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#removeRecoveredSource-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceInterface-">removeRecoveredSource</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</code>
 <div class="block">Clear the metrics and related replication queue of the specified old source</div>
 </td>
 </tr>
-<tr id="i37" class="rowColor">
+<tr id="i38" class="altColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#removeRemoteWALs-java.lang.String-java.lang.String-java.util.Collection-">removeRemoteWALs</a></span>(<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;peerId,
                 <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;remoteWALDir,
                 <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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;wals)</code>&nbsp;</td>
 </tr>
-<tr id="i38" class="altColor">
+<tr id="i39" class="rowColor">
 <td class="colFirst"><code>(package private) void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#removeSource-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceInterface-">removeSource</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</code>
 <div class="block">Clear the metrics and related replication queue of the specified old source</div>
 </td>
 </tr>
-<tr id="i39" class="rowColor">
+<tr id="i40" class="altColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#throwIOExceptionWhenFail-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager.ReplicationQueueOperation-">throwIOExceptionWhenFail</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</code>&nbsp;</td>
 </tr>
-<tr id="i40" class="altColor">
+<tr id="i41" class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#transferQueues-org.apache.hadoop.hbase.ServerName-">transferQueues</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;deadRS)</code>
 <div class="block">Transfer all the queues of the specified to this region server.</div>
@@ -725,7 +729,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>latestPaths</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;org.apache.hadoop.fs.Path&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.151">latestPaths</a></pre>
+<pre>private final&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>,org.apache.hadoop.fs.Path&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.151">latestPaths</a></pre>
 </li>
 </ul>
 <a name="logDir">
@@ -974,7 +978,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>drainSources</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.411">drainSources</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;peerId)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.410">drainSources</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;peerId)
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a>,
                          <a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationException.html" title="class in org.apache.hadoop.hbase.replication">ReplicationException</a></pre>
 <div class="block"><p>
@@ -1004,7 +1008,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>refreshSources</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.475">refreshSources</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;peerId)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.474">refreshSources</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;peerId)
                     throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Close the previous replication sources of this peer id and open new sources to trigger the new
  replication state changes or new replication config changes. Here we don't need to change
@@ -1023,7 +1027,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRecoveredSource</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.523">removeRecoveredSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.522">removeRecoveredSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
 <div class="block">Clear the metrics and related replication queue of the specified old source</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1037,7 +1041,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>finishRecoveredSource</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.534">finishRecoveredSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.533">finishRecoveredSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
 </li>
 </ul>
 <a name="removeSource-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceInterface-">
@@ -1046,7 +1050,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>removeSource</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.548">removeSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.547">removeSource</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;src)</pre>
 <div class="block">Clear the metrics and related replication queue of the specified old source</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1060,7 +1064,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>deleteQueue</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.561">deleteQueue</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;queueId)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.560">deleteQueue</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;queueId)</pre>
 <div class="block">Delete a complete queue of wals associated with a replication source</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1074,7 +1078,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>interruptOrAbortWhenFail</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.574">interruptOrAbortWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.573">interruptOrAbortWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</pre>
 <div class="block">Refresh replication source will terminate the old source first, then the source thread will be
  interrupted. Need to handle it instead of abort the region server.</div>
 </li>
@@ -1085,7 +1089,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>abortWhenFail</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.588">abortWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.587">abortWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)</pre>
 </li>
 </ul>
 <a name="throwIOExceptionWhenFail-org.apache.hadoop.hbase.replication.regionserver.ReplicationSourceManager.ReplicationQueueOperation-">
@@ -1094,7 +1098,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>throwIOExceptionWhenFail</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.596">throwIOExceptionWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.595">throwIOExceptionWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)
                                throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1108,7 +1112,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>abortAndThrowIOExceptionWhenFail</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.604">abortAndThrowIOExceptionWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.603">abortAndThrowIOExceptionWhenFail</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.ReplicationQueueOperation.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceManager.ReplicationQueueOperation</a>&nbsp;op)
                                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1122,7 +1126,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>logPositionAndCleanOldLogs</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.619">logPositionAndCleanOldLogs</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;source,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.618">logPositionAndCleanOldLogs</a>(<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;source,
                                        <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/WALEntryBatch.html" title="class in org.apache.hadoop.hbase.replication.regionserver">WALEntryBatch</a>&nbsp;entryBatch)</pre>
 <div class="block">This method will log the current position to storage. And also clean old logs from the
  replication queue.</div>
@@ -1139,7 +1143,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>cleanOldLogs</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.635">cleanOldLogs</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;log,
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.634">cleanOldLogs</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;log,
                   boolean&nbsp;inclusive,
                   <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;source)</pre>
 <div class="block">Cleans a log file and all older logs from replication queue. Called when we are sure that a log
@@ -1158,7 +1162,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRemoteWALs</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.673">removeRemoteWALs</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;peerId,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.672">removeRemoteWALs</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;peerId,
                               <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;remoteWALDir,
                               <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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;wals)
                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -1174,7 +1178,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>cleanOldLogs</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.693">cleanOldLogs</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;wals,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.692">cleanOldLogs</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;wals,
                           <a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;source)</pre>
 </li>
 </ul>
@@ -1184,7 +1188,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>preLogRoll</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.739">preLogRoll</a>(org.apache.hadoop.fs.Path&nbsp;newLog)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.738">preLogRoll</a>(org.apache.hadoop.fs.Path&nbsp;newLog)
                 throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1198,7 +1202,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>postLogRoll</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.797">postLogRoll</a>(org.apache.hadoop.fs.Path&nbsp;newLog)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.788">postLogRoll</a>(org.apache.hadoop.fs.Path&nbsp;newLog)
                  throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1212,7 +1216,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>regionServerRemoved</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.805">regionServerRemoved</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;regionserver)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.796">regionServerRemoved</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;regionserver)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationListener.html#regionServerRemoved-java.lang.String-">ReplicationListener</a></code></span></div>
 <div class="block">A region server has been removed from the local cluster</div>
 <dl>
@@ -1229,7 +1233,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>transferQueues</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.815">transferQueues</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;deadRS)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.806">transferQueues</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;deadRS)</pre>
 <div class="block">Transfer all the queues of the specified to this region server. First it tries to grab a lock
  and if it works it will move the old queues and finally will delete the old queues.
  <p>
@@ -1242,7 +1246,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>join</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.988">join</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.979">join</a>()</pre>
 <div class="block">Terminate the replication on this region server</div>
 </li>
 </ul>
@@ -1252,7 +1256,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getWALs</h4>
-<pre>public&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/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSource
 Manager.html#line.1000">getWALs</a>()</pre>
+<pre>public&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/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSource
 Manager.html#line.991">getWALs</a>()</pre>
 <div class="block">Get a copy of the wals of the normal sources on this rs</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1266,7 +1270,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getWalsByIdRecoveredQueues</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
 #line.1009">getWalsByIdRecoveredQueues</a>()</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/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/NavigableSet.html?is-external=true" title="class or interface in java.util">NavigableSet</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html
 #line.1000">getWalsByIdRecoveredQueues</a>()</pre>
 <div class="block">Get a copy of the wals of the recovered sources on this rs</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1280,7 +1284,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getSources</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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1017">getSources</a>()</pre>
+<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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1008">getSources</a>()</pre>
 <div class="block">Get a list of all the normal sources of this rs</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1294,7 +1298,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getOldSources</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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1025">getOldSources</a>()</pre>
+<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/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1016">getOldSources</a>()</pre>
 <div class="block">Get a list of all the recovered sources of this rs</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1308,7 +1312,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getSource</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1034">getSource</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;peerId)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceInterface.html" title="interface in org.apache.hadoop.hbase.replication.regionserver">ReplicationSourceInterface</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1025">getSource</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;peerId)</pre>
 <div class="block">Get the normal source for a given peer</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1322,7 +1326,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getAllQueues</h4>
-<pre><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/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1039">getAllQueues</a>()
+<pre><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/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1030">getAllQueues</a>()
                    throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1336,7 +1340,16 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getSizeOfLatestPath</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1050">getSizeOfLatestPath</a>()</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1041">getSizeOfLatestPath</a>()</pre>
+</li>
+</ul>
+<a name="getLastestPath--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>getLastestPath</h4>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;org.apache.hadoop.fs.Path&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1048">getLastestPath</a>()</pre>
 </li>
 </ul>
 <a name="getTotalBufferUsed--">
@@ -1345,7 +1358,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getTotalBufferUsed</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicLong.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicLong</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1057">getTotalBufferUsed</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicLong.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicLong</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1055">getTotalBufferUsed</a>()</pre>
 </li>
 </ul>
 <a name="getOldLogDir--">
@@ -1354,7 +1367,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getOldLogDir</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1065">getOldLogDir</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1063">getOldLogDir</a>()</pre>
 <div class="block">Get the directory where wals are archived</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1368,7 +1381,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getLogDir</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1073">getLogDir</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1071">getLogDir</a>()</pre>
 <div class="block">Get the directory where wals are stored by their RSs</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1382,7 +1395,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getFs</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1081">getFs</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1079">getFs</a>()</pre>
 <div class="block">Get the handle on the local file system</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1396,7 +1409,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getReplicationPeers</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeers.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeers</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1089">getReplicationPeers</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/replication/ReplicationPeers.html" title="class in org.apache.hadoop.hbase.replication">ReplicationPeers</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1087">getReplicationPeers</a>()</pre>
 <div class="block">Get the ReplicationPeers used by this ReplicationSourceManager</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1410,7 +1423,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>getStats</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/replication/regionserver/ReplicationSourceManager.html#line.1096">getStats</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/replication/regionserver/ReplicationSourceManager.html#line.1094">getStats</a>()</pre>
 <div class="block">Get a string representation of all the sources' metrics</div>
 </li>
 </ul>
@@ -1420,7 +1433,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>addHFileRefs</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1109">addHFileRefs</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1107">addHFileRefs</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName,
                          byte[]&nbsp;family,
                          <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/util/Pair.html" title="class in org.apache.hadoop.hbase.util">Pair</a>&lt;org.apache.hadoop.fs.Path,org.apache.hadoop.fs.Path&gt;&gt;&nbsp;pairs)
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -1436,7 +1449,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockList">
 <li class="blockList">
 <h4>cleanUpHFileRefs</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1116">cleanUpHFileRefs</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;peerId,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1114">cleanUpHFileRefs</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;peerId,
                              <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/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;files)</pre>
 </li>
 </ul>
@@ -1446,7 +1459,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/replication/Replic
 <ul class="blockListLast">
 <li class="blockList">
 <h4>activeFailoverTaskCount</h4>
-<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1120">activeFailoverTaskCount</a>()</pre>
+<pre>int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceManager.html#line.1118">activeFailoverTaskCount</a>()</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
index cd3870f..30c4e73 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
@@ -207,8 +207,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/MetricsReplicationSourceFactoryImpl.SourceHolder.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">MetricsReplicationSourceFactoryImpl.SourceHolder</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html b/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
index 034077c..c20ff47 100644
--- a/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
@@ -110,8 +110,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.FilterType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.FilterType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
index c128782..69f2dc6 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
@@ -142,9 +142,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
index 13f949c..29d7634 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
@@ -191,9 +191,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
+<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/AuthMethod.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">AuthMethod</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/util/HBaseFsck.MetaEntry.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/HBaseFsck.MetaEntry.html b/devapidocs/org/apache/hadoop/hbase/util/HBaseFsck.MetaEntry.html
index c3e22ec..44679a4 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/HBaseFsck.MetaEntry.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/HBaseFsck.MetaEntry.html
@@ -242,7 +242,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/HRegionInfo.html" title=
 <!--   -->
 </a>
 <h3>Methods inherited from interface&nbsp;org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.had
 oop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#areAdjacent-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">areAdjacent</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#createMobRegionInfo-org.apache.hadoop.hbase.TableName-">createMobRegionInfo</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getRegionNameAsString-org.apache.hadoop.hbase.client.RegionInfo-byte:A-">getRegionNameAsString</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-java.util.List-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#getShortNameToLog-org.apache.hadoop.hbase.client.RegionInfo...-">getShortNameToLog</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo
 .html#hasEncodedName-byte:A-">hasEncodedName</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo...-">toDelimitedByteArray</a>, <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html#toDelimitedByteArray-org.apache.hadoop.hbase.client.RegionInfo-">toDelimitedByteArray</a></code></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
index d7a3f61..dd95a88 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
@@ -540,13 +540,13 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLock.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLock.ReferenceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HBaseFsck.ErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HBaseFsck.ErrorReporter.ERROR_CODE</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLock.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLock.ReferenceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.PureJavaComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.PureJavaComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HBaseFsck.ErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HBaseFsck.ErrorReporter.ERROR_CODE</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
index 484daed..bd4c042 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
@@ -18,9 +18,9 @@
 <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 = "";<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 = "Thu Nov  8 14:43:17 UTC 2018";<a name="line.13"></a>
+<span class="sourceLineNo">013</span>  public static final String date = "Fri Nov  9 14:44:22 UTC 2018";<a name="line.13"></a>
 <span class="sourceLineNo">014</span>  public static final String url = "git://jenkins-websites1.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 = "ba26694ecff3f263f83aeb7b880a430c";<a name="line.15"></a>
+<span class="sourceLineNo">015</span>  public static final String srcChecksum = "2006cc481839aabfb5ea846c19b440b9";<a name="line.15"></a>
 <span class="sourceLineNo">016</span>}<a name="line.16"></a>
 
 


[30/47] hbase-site git commit: Published site at fe2265fa4a1e828b2e68ff8e42639c5942dccb1b.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9592fdb5/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
index 9d1542c..ec5f688 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.LocalityBasedCandidateGenerator.html
@@ -53,502 +53,502 @@
 <span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.LocalityType;<a name="line.45"></a>
 <span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.MoveRegionAction;<a name="line.46"></a>
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster.SwapRegionsAction;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.slf4j.Logger;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.slf4j.LoggerFactory;<a name="line.52"></a>
-<span class="sourceLineNo">053</span><a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.56"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.slf4j.Logger;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.slf4j.LoggerFactory;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hbase.thirdparty.com.google.common.base.Optional;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hbase.thirdparty.com.google.common.collect.Lists;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
 <span class="sourceLineNo">057</span><a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>/**<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;ul&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.64"></a>
-<span class="sourceLineNo">065</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> * &lt;/ul&gt;<a name="line.69"></a>
+<span class="sourceLineNo">058</span>/**<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * &lt;p&gt;This is a best effort load balancer. Given a Cost function F(C) =&amp;gt; x It will<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * randomly try and mutate the cluster to Cprime. If F(Cprime) &amp;lt; F(C) then the<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * new cluster state becomes the plan. It includes costs functions to compute the cost of:&lt;/p&gt;<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * &lt;ul&gt;<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * &lt;li&gt;Region Load&lt;/li&gt;<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;li&gt;Table Load&lt;/li&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;li&gt;Data Locality&lt;/li&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * &lt;li&gt;Memstore Sizes&lt;/li&gt;<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * &lt;li&gt;Storefile Sizes&lt;/li&gt;<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;/ul&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> *<a name="line.69"></a>
 <span class="sourceLineNo">070</span> *<a name="line.70"></a>
-<span class="sourceLineNo">071</span> *<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.74"></a>
-<span class="sourceLineNo">075</span> *<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * &lt;ul&gt;<a name="line.76"></a>
-<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.78"></a>
-<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.79"></a>
-<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.80"></a>
-<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.81"></a>
-<span class="sourceLineNo">082</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * &lt;/ul&gt;<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * configuration values:&lt;/p&gt;<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;ul&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.88"></a>
-<span class="sourceLineNo">089</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.89"></a>
-<span class="sourceLineNo">090</span> *   balancer.&lt;/li&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.91"></a>
-<span class="sourceLineNo">092</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.92"></a>
-<span class="sourceLineNo">093</span> *   mutate all servers.&lt;/li&gt;<a name="line.93"></a>
-<span class="sourceLineNo">094</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.94"></a>
-<span class="sourceLineNo">095</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.95"></a>
-<span class="sourceLineNo">096</span> *   value and the above computation.&lt;/li&gt;<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * &lt;/ul&gt;<a name="line.97"></a>
-<span class="sourceLineNo">098</span> *<a name="line.98"></a>
-<span class="sourceLineNo">099</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.99"></a>
-<span class="sourceLineNo">100</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.100"></a>
-<span class="sourceLineNo">101</span> */<a name="line.101"></a>
-<span class="sourceLineNo">102</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.102"></a>
-<span class="sourceLineNo">103</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.104"></a>
-<span class="sourceLineNo">105</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.107"></a>
-<span class="sourceLineNo">108</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  protected static final String MAX_STEPS_KEY =<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.110"></a>
-<span class="sourceLineNo">111</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.111"></a>
-<span class="sourceLineNo">112</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.113"></a>
-<span class="sourceLineNo">114</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  protected static final String KEEP_REGION_LOADS =<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.117"></a>
-<span class="sourceLineNo">118</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.118"></a>
-<span class="sourceLineNo">119</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.119"></a>
-<span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.124"></a>
-<span class="sourceLineNo">125</span><a name="line.125"></a>
-<span class="sourceLineNo">126</span>  // values are defaults<a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private int maxSteps = 1000000;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  private boolean runMaxSteps = false;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>  private int stepsPerRegion = 800;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  private int numRegionLoadsToRemember = 15;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>  private float minCostNeedBalance = 0.05f;<a name="line.132"></a>
-<span class="sourceLineNo">133</span><a name="line.133"></a>
-<span class="sourceLineNo">134</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.134"></a>
-<span class="sourceLineNo">135</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.135"></a>
-<span class="sourceLineNo">136</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.136"></a>
-<span class="sourceLineNo">137</span><a name="line.137"></a>
-<span class="sourceLineNo">138</span>  // to save and report costs to JMX<a name="line.138"></a>
-<span class="sourceLineNo">139</span>  private Double curOverallCost = 0d;<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  private Double[] tempFunctionCosts;<a name="line.140"></a>
-<span class="sourceLineNo">141</span>  private Double[] curFunctionCosts;<a name="line.141"></a>
-<span class="sourceLineNo">142</span><a name="line.142"></a>
-<span class="sourceLineNo">143</span>  // Keep locality based picker and cost function to alert them<a name="line.143"></a>
-<span class="sourceLineNo">144</span>  // when new services are offered<a name="line.144"></a>
-<span class="sourceLineNo">145</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>  private ServerLocalityCostFunction localityCost;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>  private boolean isByTable = false;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  private TableName tableName = null;<a name="line.151"></a>
-<span class="sourceLineNo">152</span><a name="line.152"></a>
-<span class="sourceLineNo">153</span>  /**<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * default MetricsBalancer<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   */<a name="line.156"></a>
-<span class="sourceLineNo">157</span>  public StochasticLoadBalancer() {<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    super(new MetricsStochasticBalancer());<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  }<a name="line.159"></a>
-<span class="sourceLineNo">160</span><a name="line.160"></a>
-<span class="sourceLineNo">161</span>  @Override<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  public void onConfigurationChange(Configuration conf) {<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    setConf(conf);<a name="line.163"></a>
-<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
-<span class="sourceLineNo">167</span>  public synchronized void setConf(Configuration conf) {<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    super.setConf(conf);<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.172"></a>
-<span class="sourceLineNo">173</span><a name="line.173"></a>
-<span class="sourceLineNo">174</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    if (localityCandidateGenerator == null) {<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    }<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.181"></a>
-<span class="sourceLineNo">182</span><a name="line.182"></a>
-<span class="sourceLineNo">183</span>    if (this.candidateGenerators == null) {<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      candidateGenerators = Lists.newArrayList();<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      new ReadRequestCostFunction(conf),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      new CPRequestCostFunction(conf),<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      new WriteRequestCostFunction(conf),<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      new MemStoreSizeCostFunction(conf),<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      new StoreFileCostFunction(conf)<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    };<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.197"></a>
-<span class="sourceLineNo">198</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.198"></a>
-<span class="sourceLineNo">199</span>    costFunctions = new CostFunction[]{<a name="line.199"></a>
-<span class="sourceLineNo">200</span>      new RegionCountSkewCostFunction(conf),<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      new MoveCostFunction(conf),<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      localityCost,<a name="line.203"></a>
-<span class="sourceLineNo">204</span>      rackLocalityCost,<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      new TableSkewCostFunction(conf),<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      regionReplicaHostCostFunction,<a name="line.206"></a>
-<span class="sourceLineNo">207</span>      regionReplicaRackCostFunction,<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      regionLoadFunctions[0],<a name="line.208"></a>
-<span class="sourceLineNo">209</span>      regionLoadFunctions[1],<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      regionLoadFunctions[2],<a name="line.210"></a>
-<span class="sourceLineNo">211</span>      regionLoadFunctions[3],<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      regionLoadFunctions[4]<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    };<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.215"></a>
-<span class="sourceLineNo">216</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.217"></a>
-<span class="sourceLineNo">218</span>  }<a name="line.218"></a>
-<span class="sourceLineNo">219</span><a name="line.219"></a>
-<span class="sourceLineNo">220</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Override<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  protected void setSlop(Configuration conf) {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.226"></a>
-<span class="sourceLineNo">227</span>  }<a name="line.227"></a>
-<span class="sourceLineNo">228</span><a name="line.228"></a>
-<span class="sourceLineNo">229</span>  @Override<a name="line.229"></a>
-<span class="sourceLineNo">230</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    super.setClusterMetrics(st);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    updateRegionLoad();<a name="line.232"></a>
-<span class="sourceLineNo">233</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>      cost.setClusterMetrics(st);<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    // update metrics size<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    try {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      // by-table or ensemble mode<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      int functionsCount = getCostFunctionNames().length;<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.243"></a>
-<span class="sourceLineNo">244</span>    } catch (Exception e) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>      LOG.error("failed to get the size of all tables", e);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    }<a name="line.246"></a>
-<span class="sourceLineNo">247</span>  }<a name="line.247"></a>
-<span class="sourceLineNo">248</span><a name="line.248"></a>
-<span class="sourceLineNo">249</span>  /**<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * Update the number of metrics that are reported to JMX<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  public void updateMetricsSize(int size) {<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.253"></a>
-<span class="sourceLineNo">254</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    }<a name="line.255"></a>
-<span class="sourceLineNo">256</span>  }<a name="line.256"></a>
-<span class="sourceLineNo">257</span><a name="line.257"></a>
-<span class="sourceLineNo">258</span>  @Override<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    super.setMasterServices(masterServices);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    this.localityCost.setServices(masterServices);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.262"></a>
-<span class="sourceLineNo">263</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>  }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>  @Override<a name="line.266"></a>
-<span class="sourceLineNo">267</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    regionReplicaHostCostFunction.init(c);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>    regionReplicaRackCostFunction.init(c);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    return false;<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  @Override<a name="line.275"></a>
-<span class="sourceLineNo">276</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.277"></a>
-<span class="sourceLineNo">278</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (LOG.isDebugEnabled()) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.280"></a>
-<span class="sourceLineNo">281</span>            + " active regionserver(s)");<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      return false;<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    }<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return true;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>    double total = 0.0;<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    float sumMultiplier = 0.0f;<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    for (CostFunction c : costFunctions) {<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      float multiplier = c.getMultiplier();<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      if (multiplier &lt;= 0) {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>        continue;<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      }<a name="line.295"></a>
-<span class="sourceLineNo">296</span>      if (!c.isNeeded()) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.297"></a>
-<span class="sourceLineNo">298</span>        continue;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      sumMultiplier += multiplier;<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      total += c.cost() * multiplier;<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      if (LOG.isTraceEnabled()) {<a name="line.306"></a>
-<span class="sourceLineNo">307</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.307"></a>
-<span class="sourceLineNo">308</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.308"></a>
-<span class="sourceLineNo">309</span>          + minCostNeedBalance);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>      }<a name="line.310"></a>
-<span class="sourceLineNo">311</span>      return false;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>    }<a name="line.312"></a>
-<span class="sourceLineNo">313</span>    return true;<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  }<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
-<span class="sourceLineNo">317</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    this.tableName = tableName;<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    return balanceCluster(clusterState);<a name="line.320"></a>
-<span class="sourceLineNo">321</span>  }<a name="line.321"></a>
-<span class="sourceLineNo">322</span><a name="line.322"></a>
-<span class="sourceLineNo">323</span>  @VisibleForTesting<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.325"></a>
-<span class="sourceLineNo">326</span>            .generate(cluster);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
-<span class="sourceLineNo">328</span><a name="line.328"></a>
-<span class="sourceLineNo">329</span>  /**<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * should always approach the optimal state given enough steps.<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   */<a name="line.332"></a>
-<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
-<span class="sourceLineNo">334</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      return plans;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (clusterState.size() &lt;= 2) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        return null;<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      }<a name="line.344"></a>
-<span class="sourceLineNo">345</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      clusterState.remove(masterServerName);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>    }<a name="line.347"></a>
-<span class="sourceLineNo">348</span><a name="line.348"></a>
-<span class="sourceLineNo">349</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    // instantiating the storefile infos can be quite expensive.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.351"></a>
-<span class="sourceLineNo">352</span>    // be used in any computations.<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    RegionLocationFinder finder = null;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>      finder = this.regionFinder;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    }<a name="line.357"></a>
-<span class="sourceLineNo">358</span><a name="line.358"></a>
-<span class="sourceLineNo">359</span>    //The clusterState that is given to this method contains the state<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    //of all the regions in the table(s) (that's true today)<a name="line.360"></a>
-<span class="sourceLineNo">361</span>    // Keep track of servers to iterate through them.<a name="line.361"></a>
-<span class="sourceLineNo">362</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.362"></a>
-<span class="sourceLineNo">363</span><a name="line.363"></a>
-<span class="sourceLineNo">364</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>    initCosts(cluster);<a name="line.366"></a>
-<span class="sourceLineNo">367</span><a name="line.367"></a>
-<span class="sourceLineNo">368</span>    if (!needsBalance(cluster)) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>      return null;<a name="line.369"></a>
-<span class="sourceLineNo">370</span>    }<a name="line.370"></a>
-<span class="sourceLineNo">371</span><a name="line.371"></a>
-<span class="sourceLineNo">372</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    curOverallCost = currentCost;<a name="line.373"></a>
-<span class="sourceLineNo">374</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
-<span class="sourceLineNo">377</span>    double initCost = currentCost;<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    double newCost = currentCost;<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    long computedMaxSteps;<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    if (runMaxSteps) {<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.382"></a>
-<span class="sourceLineNo">383</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.383"></a>
-<span class="sourceLineNo">384</span>    } else {<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.385"></a>
-<span class="sourceLineNo">386</span>          (long)cluster.numServers;<a name="line.386"></a>
-<span class="sourceLineNo">387</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.387"></a>
-<span class="sourceLineNo">388</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.388"></a>
-<span class="sourceLineNo">389</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.389"></a>
-<span class="sourceLineNo">390</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.390"></a>
-<span class="sourceLineNo">391</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.391"></a>
-<span class="sourceLineNo">392</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.392"></a>
-<span class="sourceLineNo">393</span>            maxRunningTime);<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      }<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    }<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.397"></a>
-<span class="sourceLineNo">398</span><a name="line.398"></a>
-<span class="sourceLineNo">399</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    long step;<a name="line.400"></a>
-<span class="sourceLineNo">401</span><a name="line.401"></a>
-<span class="sourceLineNo">402</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      Cluster.Action action = nextAction(cluster);<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>      if (action.type == Type.NULL) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        continue;<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>      cluster.doAction(action);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      updateCostsWithAction(cluster, action);<a name="line.410"></a>
-<span class="sourceLineNo">411</span><a name="line.411"></a>
-<span class="sourceLineNo">412</span>      newCost = computeCost(cluster, currentCost);<a name="line.412"></a>
-<span class="sourceLineNo">413</span><a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // Should this be kept?<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      if (newCost &lt; currentCost) {<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        currentCost = newCost;<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // save for JMX<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>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        // Put things back the way they were before.<a name="line.424"></a>
-<span class="sourceLineNo">425</span>        // TODO: undo by remembering old values<a name="line.425"></a>
-<span class="sourceLineNo">426</span>        Action undoAction = action.undoAction();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        cluster.doAction(undoAction);<a name="line.427"></a>
-<span class="sourceLineNo">428</span>        updateCostsWithAction(cluster, undoAction);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      }<a name="line.429"></a>
-<span class="sourceLineNo">430</span><a name="line.430"></a>
-<span class="sourceLineNo">431</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          maxRunningTime) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>        break;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>      }<a name="line.434"></a>
-<span class="sourceLineNo">435</span>    }<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    long endTime = EnvironmentEdgeManager.currentTime();<a name="line.436"></a>
-<span class="sourceLineNo">437</span><a name="line.437"></a>
-<span class="sourceLineNo">438</span>    metricsBalancer.balanceCluster(endTime - startTime);<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>    // update costs metrics<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    updateStochasticCosts(tableName, curOverallCost, curFunctionCosts);<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    if (initCost &gt; currentCost) {<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      plans = createRegionPlans(cluster);<a name="line.443"></a>
-<span class="sourceLineNo">444</span>      LOG.info("Finished computing new load balance plan. Computation took {}" +<a name="line.444"></a>
-<span class="sourceLineNo">445</span>        " to try {} different iterations.  Found a solution that moves " +<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        "{} regions; Going from a computed cost of {}" +<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        " to a new cost of {}", java.time.Duration.ofMillis(endTime - startTime),<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        step, plans.size(), initCost, currentCost);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      return plans;<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    LOG.info("Could not find a better load balance plan.  Tried {} different configurations in " +<a name="line.451"></a>
-<span class="sourceLineNo">452</span>      "{}, and did not find anything with a computed cost less than {}", step,<a name="line.452"></a>
-<span class="sourceLineNo">453</span>      java.time.Duration.ofMillis(endTime - startTime), initCost);<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    return null;<a name="line.454"></a>
-<span class="sourceLineNo">455</span>  }<a name="line.455"></a>
-<span class="sourceLineNo">456</span><a name="line.456"></a>
-<span class="sourceLineNo">457</span>  /**<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   * update costs to JMX<a name="line.458"></a>
-<span class="sourceLineNo">459</span>   */<a name="line.459"></a>
-<span class="sourceLineNo">460</span>  private void updateStochasticCosts(TableName tableName, Double overall, Double[] subCosts) {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    if (tableName == null) return;<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>    // check if the metricsBalancer is MetricsStochasticBalancer before casting<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      MetricsStochasticBalancer balancer = (MetricsStochasticBalancer) metricsBalancer;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      // overall cost<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      balancer.updateStochasticCost(tableName.getNameAsString(),<a name="line.467"></a>
-<span class="sourceLineNo">468</span>        "Overall", "Overall cost", overall);<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      // each cost function<a name="line.470"></a>
-<span class="sourceLineNo">471</span>      for (int i = 0; i &lt; costFunctions.length; i++) {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>        CostFunction costFunction = costFunctions[i];<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        String costFunctionName = costFunction.getClass().getSimpleName();<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        Double costPercent = (overall == 0) ? 0 : (subCosts[i] / overall);<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        // TODO: cost function may need a specific description<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        balancer.updateStochasticCost(tableName.getNameAsString(), costFunctionName,<a name="line.476"></a>
-<span class="sourceLineNo">477</span>          "The percent of " + costFunctionName, costPercent);<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>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  private String functionCost() {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    StringBuilder builder = new StringBuilder();<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    for (CostFunction c:costFunctions) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      builder.append(c.getClass().getSimpleName());<a name="line.485"></a>
-<span class="sourceLineNo">486</span>      builder.append(" : (");<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      builder.append(c.getMultiplier());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>      builder.append(", ");<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      builder.append(c.cost());<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      builder.append("); ");<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    }<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return builder.toString();<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  }<a name="line.493"></a>
-<span class="sourceLineNo">494</span><a name="line.494"></a>
-<span class="sourceLineNo">495</span>  /**<a name="line.495"></a>
-<span class="sourceLineNo">496</span>   * Create all of the RegionPlan's needed to move from the initial cluster state to the desired<a name="line.496"></a>
-<span class="sourceLineNo">497</span>   * state.<a name="line.497"></a>
-<span class="sourceLineNo">498</span>   *<a name="line.498"></a>
-<span class="sourceLineNo">499</span>   * @param cluster The state of the cluster<a name="line.499"></a>
-<span class="sourceLineNo">500</span>   * @return List of RegionPlan's that represent the moves needed to get to desired final state.<a name="line.500"></a>
-<span class="sourceLineNo">501</span>   */<a name="line.501"></a>
-<span class="sourceLineNo">502</span>  private List&lt;RegionPlan&gt; createRegionPlans(Cluster cluster) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    List&lt;RegionPlan&gt; plans = new LinkedList&lt;&gt;();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    for (int regionIndex = 0;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>         regionIndex &lt; cluster.regionIndexToServerIndex.length; regionIndex++) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>      int initialServerIndex = cluster.initialRegionIndexToServerIndex[regionIndex];<a name="line.506"></a>
-<span class="sourceLineNo">507</span>      int newServerIndex = cluster.regionIndexToServerIndex[regionIndex];<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>      if (initialServerIndex != newServerIndex) {<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        RegionInfo region = cluster.regions[regionIndex];<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        ServerName initialServer = cluster.servers[initialServerIndex];<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        ServerName newServer = cluster.servers[newServerIndex];<a name="line.512"></a>
-<span class="sourceLineNo">513</span><a name="line.513"></a>
-<span class="sourceLineNo">514</span>        if (LOG.isTraceEnabled()) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          LOG.trace("Moving Region " + region.getEncodedName() + " from server "<a name="line.515"></a>
-<span class="sourceLineNo">516</span>              + initialServer.getHostname() + " to " + newServer.getHostname());<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        RegionPlan rp = new RegionPlan(region, initialServer, newServer);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        plans.add(rp);<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
-<span class="sourceLineNo">522</span>    return plans;<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>   * Store the current region loads.<a name="line.526"></a>
-<span class="sourceLineNo">527</span>   */<a name="line.527"></a>
-<span class="sourceLineNo">528</span>  private synchronized void updateRegionLoad() {<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    // We create a new hashmap so that regions that are no longer there are removed.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>    // However we temporarily need the old loads so we can use them to keep the rolling average.<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; oldLoads = loads;<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    loads = new HashMap&lt;&gt;();<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>    clusterStatus.getLiveServerMetrics().forEach((ServerName sn, ServerMetrics sm) -&gt; {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>      sm.getRegionMetrics().forEach((byte[] regionName, RegionMetrics rm) -&gt; {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>        Deque&lt;BalancerRegionLoad&gt; rLoads = oldLoads.get(Bytes.toString(regionName));<a name="line.536"></a>
+<span class="sourceLineNo">071</span> * &lt;p&gt;Every cost function returns a number between 0 and 1 inclusive; where 0 is the lowest cost<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * best solution, and 1 is the highest possible cost and the worst solution.  The computed costs are<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * scaled by their respective multipliers:&lt;/p&gt;<a name="line.73"></a>
+<span class="sourceLineNo">074</span> *<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * &lt;ul&gt;<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *   &lt;li&gt;hbase.master.balancer.stochastic.regionLoadCost&lt;/li&gt;<a name="line.76"></a>
+<span class="sourceLineNo">077</span> *   &lt;li&gt;hbase.master.balancer.stochastic.moveCost&lt;/li&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> *   &lt;li&gt;hbase.master.balancer.stochastic.tableLoadCost&lt;/li&gt;<a name="line.78"></a>
+<span class="sourceLineNo">079</span> *   &lt;li&gt;hbase.master.balancer.stochastic.localityCost&lt;/li&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *   &lt;li&gt;hbase.master.balancer.stochastic.memstoreSizeCost&lt;/li&gt;<a name="line.80"></a>
+<span class="sourceLineNo">081</span> *   &lt;li&gt;hbase.master.balancer.stochastic.storefileSizeCost&lt;/li&gt;<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * &lt;/ul&gt;<a name="line.82"></a>
+<span class="sourceLineNo">083</span> *<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p&gt;In addition to the above configurations, the balancer can be tuned by the following<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * configuration values:&lt;/p&gt;<a name="line.85"></a>
+<span class="sourceLineNo">086</span> * &lt;ul&gt;<a name="line.86"></a>
+<span class="sourceLineNo">087</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxMoveRegions which<a name="line.87"></a>
+<span class="sourceLineNo">088</span> *   controls what the max number of regions that can be moved in a single invocation of this<a name="line.88"></a>
+<span class="sourceLineNo">089</span> *   balancer.&lt;/li&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *   &lt;li&gt;hbase.master.balancer.stochastic.stepsPerRegion is the coefficient by which the number of<a name="line.90"></a>
+<span class="sourceLineNo">091</span> *   regions is multiplied to try and get the number of times the balancer will<a name="line.91"></a>
+<span class="sourceLineNo">092</span> *   mutate all servers.&lt;/li&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> *   &lt;li&gt;hbase.master.balancer.stochastic.maxSteps which controls the maximum number of times that<a name="line.93"></a>
+<span class="sourceLineNo">094</span> *   the balancer will try and mutate all the servers. The balancer will use the minimum of this<a name="line.94"></a>
+<span class="sourceLineNo">095</span> *   value and the above computation.&lt;/li&gt;<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;/ul&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> *<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * &lt;p&gt;This balancer is best used with hbase.master.loadbalance.bytable set to false<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * so that the balancer gets the full picture of all loads on the cluster.&lt;/p&gt;<a name="line.99"></a>
+<span class="sourceLineNo">100</span> */<a name="line.100"></a>
+<span class="sourceLineNo">101</span>@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IS2_INCONSISTENT_SYNC",<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  justification="Complaint is about costFunctions not being synchronized; not end of the world")<a name="line.103"></a>
+<span class="sourceLineNo">104</span>public class StochasticLoadBalancer extends BaseLoadBalancer {<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  protected static final String STEPS_PER_REGION_KEY =<a name="line.106"></a>
+<span class="sourceLineNo">107</span>      "hbase.master.balancer.stochastic.stepsPerRegion";<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  protected static final String MAX_STEPS_KEY =<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      "hbase.master.balancer.stochastic.maxSteps";<a name="line.109"></a>
+<span class="sourceLineNo">110</span>  protected static final String RUN_MAX_STEPS_KEY =<a name="line.110"></a>
+<span class="sourceLineNo">111</span>      "hbase.master.balancer.stochastic.runMaxSteps";<a name="line.111"></a>
+<span class="sourceLineNo">112</span>  protected static final String MAX_RUNNING_TIME_KEY =<a name="line.112"></a>
+<span class="sourceLineNo">113</span>      "hbase.master.balancer.stochastic.maxRunningTime";<a name="line.113"></a>
+<span class="sourceLineNo">114</span>  protected static final String KEEP_REGION_LOADS =<a name="line.114"></a>
+<span class="sourceLineNo">115</span>      "hbase.master.balancer.stochastic.numRegionLoadsToRemember";<a name="line.115"></a>
+<span class="sourceLineNo">116</span>  private static final String TABLE_FUNCTION_SEP = "_";<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  protected static final String MIN_COST_NEED_BALANCE_KEY =<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      "hbase.master.balancer.stochastic.minCostNeedBalance";<a name="line.118"></a>
+<span class="sourceLineNo">119</span><a name="line.119"></a>
+<span class="sourceLineNo">120</span>  protected static final Random RANDOM = new Random(System.currentTimeMillis());<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  private static final Logger LOG = LoggerFactory.getLogger(StochasticLoadBalancer.class);<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  Map&lt;String, Deque&lt;BalancerRegionLoad&gt;&gt; loads = new HashMap&lt;&gt;();<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>  // values are defaults<a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private int maxSteps = 1000000;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>  private boolean runMaxSteps = false;<a name="line.127"></a>
+<span class="sourceLineNo">128</span>  private int stepsPerRegion = 800;<a name="line.128"></a>
+<span class="sourceLineNo">129</span>  private long maxRunningTime = 30 * 1000 * 1; // 30 seconds.<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  private int numRegionLoadsToRemember = 15;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>  private float minCostNeedBalance = 0.05f;<a name="line.131"></a>
+<span class="sourceLineNo">132</span><a name="line.132"></a>
+<span class="sourceLineNo">133</span>  private List&lt;CandidateGenerator&gt; candidateGenerators;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>  private CostFromRegionLoadFunction[] regionLoadFunctions;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>  private CostFunction[] costFunctions; // FindBugs: Wants this protected; IS2_INCONSISTENT_SYNC<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>  // to save and report costs to JMX<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  private Double curOverallCost = 0d;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  private Double[] tempFunctionCosts;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private Double[] curFunctionCosts;<a name="line.140"></a>
+<span class="sourceLineNo">141</span><a name="line.141"></a>
+<span class="sourceLineNo">142</span>  // Keep locality based picker and cost function to alert them<a name="line.142"></a>
+<span class="sourceLineNo">143</span>  // when new services are offered<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  private LocalityBasedCandidateGenerator localityCandidateGenerator;<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  private ServerLocalityCostFunction localityCost;<a name="line.145"></a>
+<span class="sourceLineNo">146</span>  private RackLocalityCostFunction rackLocalityCost;<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  private RegionReplicaHostCostFunction regionReplicaHostCostFunction;<a name="line.147"></a>
+<span class="sourceLineNo">148</span>  private RegionReplicaRackCostFunction regionReplicaRackCostFunction;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>  private boolean isByTable = false;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  private TableName tableName = null;<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  /**<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * The constructor that pass a MetricsStochasticBalancer to BaseLoadBalancer to replace its<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * default MetricsBalancer<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   */<a name="line.155"></a>
+<span class="sourceLineNo">156</span>  public StochasticLoadBalancer() {<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    super(new MetricsStochasticBalancer());<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public void onConfigurationChange(Configuration conf) {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    setConf(conf);<a name="line.162"></a>
+<span class="sourceLineNo">163</span>  }<a name="line.163"></a>
+<span class="sourceLineNo">164</span><a name="line.164"></a>
+<span class="sourceLineNo">165</span>  @Override<a name="line.165"></a>
+<span class="sourceLineNo">166</span>  public synchronized void setConf(Configuration conf) {<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    super.setConf(conf);<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    maxSteps = conf.getInt(MAX_STEPS_KEY, maxSteps);<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    stepsPerRegion = conf.getInt(STEPS_PER_REGION_KEY, stepsPerRegion);<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    maxRunningTime = conf.getLong(MAX_RUNNING_TIME_KEY, maxRunningTime);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    runMaxSteps = conf.getBoolean(RUN_MAX_STEPS_KEY, runMaxSteps);<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    numRegionLoadsToRemember = conf.getInt(KEEP_REGION_LOADS, numRegionLoadsToRemember);<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    isByTable = conf.getBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    minCostNeedBalance = conf.getFloat(MIN_COST_NEED_BALANCE_KEY, minCostNeedBalance);<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    if (localityCandidateGenerator == null) {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      localityCandidateGenerator = new LocalityBasedCandidateGenerator(services);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    }<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    localityCost = new ServerLocalityCostFunction(conf, services);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    rackLocalityCost = new RackLocalityCostFunction(conf, services);<a name="line.180"></a>
+<span class="sourceLineNo">181</span><a name="line.181"></a>
+<span class="sourceLineNo">182</span>    if (this.candidateGenerators == null) {<a name="line.182"></a>
+<span class="sourceLineNo">183</span>      candidateGenerators = Lists.newArrayList();<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      candidateGenerators.add(new RandomCandidateGenerator());<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      candidateGenerators.add(new LoadCandidateGenerator());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      candidateGenerators.add(localityCandidateGenerator);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      candidateGenerators.add(new RegionReplicaRackCandidateGenerator());<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    }<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    regionLoadFunctions = new CostFromRegionLoadFunction[] {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      new ReadRequestCostFunction(conf),<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      new CPRequestCostFunction(conf),<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      new WriteRequestCostFunction(conf),<a name="line.192"></a>
+<span class="sourceLineNo">193</span>      new MemStoreSizeCostFunction(conf),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      new StoreFileCostFunction(conf)<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    };<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    regionReplicaHostCostFunction = new RegionReplicaHostCostFunction(conf);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    regionReplicaRackCostFunction = new RegionReplicaRackCostFunction(conf);<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    costFunctions = new CostFunction[]{<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      new RegionCountSkewCostFunction(conf),<a name="line.199"></a>
+<span class="sourceLineNo">200</span>      new PrimaryRegionCountSkewCostFunction(conf),<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      new MoveCostFunction(conf),<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      localityCost,<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      rackLocalityCost,<a name="line.203"></a>
+<span class="sourceLineNo">204</span>      new TableSkewCostFunction(conf),<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      regionReplicaHostCostFunction,<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      regionReplicaRackCostFunction,<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      regionLoadFunctions[0],<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      regionLoadFunctions[1],<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      regionLoadFunctions[2],<a name="line.209"></a>
+<span class="sourceLineNo">210</span>      regionLoadFunctions[3],<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      regionLoadFunctions[4]<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    };<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    curFunctionCosts= new Double[costFunctions.length];<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    tempFunctionCosts= new Double[costFunctions.length];<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    LOG.info("Loaded config; maxSteps=" + maxSteps + ", stepsPerRegion=" + stepsPerRegion +<a name="line.215"></a>
+<span class="sourceLineNo">216</span>        ", maxRunningTime=" + maxRunningTime + ", isByTable=" + isByTable + ", etc.");<a name="line.216"></a>
+<span class="sourceLineNo">217</span>  }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>  protected void setCandidateGenerators(List&lt;CandidateGenerator&gt; customCandidateGenerators) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    this.candidateGenerators = customCandidateGenerators;<a name="line.220"></a>
+<span class="sourceLineNo">221</span>  }<a name="line.221"></a>
+<span class="sourceLineNo">222</span><a name="line.222"></a>
+<span class="sourceLineNo">223</span>  @Override<a name="line.223"></a>
+<span class="sourceLineNo">224</span>  protected void setSlop(Configuration conf) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    this.slop = conf.getFloat("hbase.regions.slop", 0.001F);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>  }<a name="line.226"></a>
+<span class="sourceLineNo">227</span><a name="line.227"></a>
+<span class="sourceLineNo">228</span>  @Override<a name="line.228"></a>
+<span class="sourceLineNo">229</span>  public synchronized void setClusterMetrics(ClusterMetrics st) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    super.setClusterMetrics(st);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    updateRegionLoad();<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    for(CostFromRegionLoadFunction cost : regionLoadFunctions) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      cost.setClusterMetrics(st);<a name="line.233"></a>
+<span class="sourceLineNo">234</span>    }<a name="line.234"></a>
+<span class="sourceLineNo">235</span><a name="line.235"></a>
+<span class="sourceLineNo">236</span>    // update metrics size<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    try {<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      // by-table or ensemble mode<a name="line.238"></a>
+<span class="sourceLineNo">239</span>      int tablesCount = isByTable ? services.getTableDescriptors().getAll().size() : 1;<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      int functionsCount = getCostFunctionNames().length;<a name="line.240"></a>
+<span class="sourceLineNo">241</span><a name="line.241"></a>
+<span class="sourceLineNo">242</span>      updateMetricsSize(tablesCount * (functionsCount + 1)); // +1 for overall<a name="line.242"></a>
+<span class="sourceLineNo">243</span>    } catch (Exception e) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      LOG.error("failed to get the size of all tables", e);<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span>  }<a name="line.246"></a>
+<span class="sourceLineNo">247</span><a name="line.247"></a>
+<span class="sourceLineNo">248</span>  /**<a name="line.248"></a>
+<span class="sourceLineNo">249</span>   * Update the number of metrics that are reported to JMX<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>  public void updateMetricsSize(int size) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>    if (metricsBalancer instanceof MetricsStochasticBalancer) {<a name="line.252"></a>
+<span class="sourceLineNo">253</span>        ((MetricsStochasticBalancer) metricsBalancer).updateMetricsSize(size);<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  }<a name="line.255"></a>
+<span class="sourceLineNo">256</span><a name="line.256"></a>
+<span class="sourceLineNo">257</span>  @Override<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  public synchronized void setMasterServices(MasterServices masterServices) {<a name="line.258"></a>
+<span class="sourceLineNo">259</span>    super.setMasterServices(masterServices);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    this.localityCost.setServices(masterServices);<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    this.rackLocalityCost.setServices(masterServices);<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    this.localityCandidateGenerator.setServices(masterServices);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Override<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  protected synchronized boolean areSomeRegionReplicasColocated(Cluster c) {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    regionReplicaHostCostFunction.init(c);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>    if (regionReplicaHostCostFunction.cost() &gt; 0) return true;<a name="line.268"></a>
+<span class="sourceLineNo">269</span>    regionReplicaRackCostFunction.init(c);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    if (regionReplicaRackCostFunction.cost() &gt; 0) return true;<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    return false;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
+<span class="sourceLineNo">273</span><a name="line.273"></a>
+<span class="sourceLineNo">274</span>  @Override<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  protected boolean needsBalance(Cluster cluster) {<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    ClusterLoadState cs = new ClusterLoadState(cluster.clusterState);<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    if (cs.getNumServers() &lt; MIN_SERVER_BALANCE) {<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      if (LOG.isDebugEnabled()) {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>        LOG.debug("Not running balancer because only " + cs.getNumServers()<a name="line.279"></a>
+<span class="sourceLineNo">280</span>            + " active regionserver(s)");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      }<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      return false;<a name="line.282"></a>
+<span class="sourceLineNo">283</span>    }<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    if (areSomeRegionReplicasColocated(cluster)) {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return true;<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span><a name="line.287"></a>
+<span class="sourceLineNo">288</span>    double total = 0.0;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    float sumMultiplier = 0.0f;<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    for (CostFunction c : costFunctions) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      float multiplier = c.getMultiplier();<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      if (multiplier &lt;= 0) {<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        continue;<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      }<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      if (!c.isNeeded()) {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>        LOG.debug("{} not needed", c.getClass().getSimpleName());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        continue;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      }<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      sumMultiplier += multiplier;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      total += c.cost() * multiplier;<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
+<span class="sourceLineNo">302</span><a name="line.302"></a>
+<span class="sourceLineNo">303</span>    if (total &lt;= 0 || sumMultiplier &lt;= 0<a name="line.303"></a>
+<span class="sourceLineNo">304</span>        || (sumMultiplier &gt; 0 &amp;&amp; (total / sumMultiplier) &lt; minCostNeedBalance)) {<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      if (LOG.isTraceEnabled()) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>        LOG.trace("Skipping load balancing because balanced cluster; " + "total cost is " + total<a name="line.306"></a>
+<span class="sourceLineNo">307</span>          + ", sum multiplier is " + sumMultiplier + " min cost which need balance is "<a name="line.307"></a>
+<span class="sourceLineNo">308</span>          + minCostNeedBalance);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>      }<a name="line.309"></a>
+<span class="sourceLineNo">310</span>      return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    return true;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @Override<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(TableName tableName, Map&lt;ServerName,<a name="line.316"></a>
+<span class="sourceLineNo">317</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>    this.tableName = tableName;<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    return balanceCluster(clusterState);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>  @VisibleForTesting<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  Cluster.Action nextAction(Cluster cluster) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    return candidateGenerators.get(RANDOM.nextInt(candidateGenerators.size()))<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            .generate(cluster);<a name="line.325"></a>
+<span class="sourceLineNo">326</span>  }<a name="line.326"></a>
+<span class="sourceLineNo">327</span><a name="line.327"></a>
+<span class="sourceLineNo">328</span>  /**<a name="line.328"></a>
+<span class="sourceLineNo">329</span>   * Given the cluster state this will try and approach an optimal balance. This<a name="line.329"></a>
+<span class="sourceLineNo">330</span>   * should always approach the optimal state given enough steps.<a name="line.330"></a>
+<span class="sourceLineNo">331</span>   */<a name="line.331"></a>
+<span class="sourceLineNo">332</span>  @Override<a name="line.332"></a>
+<span class="sourceLineNo">333</span>  public synchronized List&lt;RegionPlan&gt; balanceCluster(Map&lt;ServerName,<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    List&lt;RegionInfo&gt;&gt; clusterState) {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    List&lt;RegionPlan&gt; plans = balanceMasterRegions(clusterState);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    if (plans != null || clusterState == null || clusterState.size() &lt;= 1) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      return plans;<a name="line.337"></a>
+<span class="sourceLineNo">338</span>    }<a name="line.338"></a>
+<span class="sourceLineNo">339</span><a name="line.339"></a>
+<span class="sourceLineNo">340</span>    if (masterServerName != null &amp;&amp; clusterState.containsKey(masterServerName)) {<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      if (clusterState.size() &lt;= 2) {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        return null;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
+<span class="sourceLineNo">344</span>      clusterState = new HashMap&lt;&gt;(clusterState);<a name="line.344"></a>
+<span class="sourceLineNo">345</span>      clusterState.remove(masterServerName);<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    }<a name="line.346"></a>
+<span class="sourceLineNo">347</span><a name="line.347"></a>
+<span class="sourceLineNo">348</span>    // On clusters with lots of HFileLinks or lots of reference files,<a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // instantiating the storefile infos can be quite expensive.<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    // Allow turning this feature off if the locality cost is not going to<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    // be used in any computations.<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    RegionLocationFinder finder = null;<a name="line.352"></a>
+<span class="sourceLineNo">353</span>    if ((this.localityCost != null &amp;&amp; this.localityCost.getMultiplier() &gt; 0)<a name="line.353"></a>
+<span class="sourceLineNo">354</span>        || (this.rackLocalityCost != null &amp;&amp; this.rackLocalityCost.getMultiplier() &gt; 0)) {<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      finder = this.regionFinder;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    }<a name="line.356"></a>
+<span class="sourceLineNo">357</span><a name="line.357"></a>
+<span class="sourceLineNo">358</span>    //The clusterState that is given to this method contains the state<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    //of all the regions in the table(s) (that's true today)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    // Keep track of servers to iterate through them.<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    Cluster cluster = new Cluster(clusterState, loads, finder, rackManager);<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>    long startTime = EnvironmentEdgeManager.currentTime();<a name="line.363"></a>
+<span class="sourceLineNo">364</span><a name="line.364"></a>
+<span class="sourceLineNo">365</span>    initCosts(cluster);<a name="line.365"></a>
+<span class="sourceLineNo">366</span><a name="line.366"></a>
+<span class="sourceLineNo">367</span>    if (!needsBalance(cluster)) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      return null;<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    }<a name="line.369"></a>
+<span class="sourceLineNo">370</span><a name="line.370"></a>
+<span class="sourceLineNo">371</span>    double currentCost = computeCost(cluster, Double.MAX_VALUE);<a name="line.371"></a>
+<span class="sourceLineNo">372</span>    curOverallCost = currentCost;<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    }<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    double initCost = currentCost;<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    double newCost = currentCost;<a name="line.377"></a>
+<span class="sourceLineNo">378</span><a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long computedMaxSteps;<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    if (runMaxSteps) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      computedMaxSteps = Math.max(this.maxSteps,<a name="line.381"></a>
+<span class="sourceLineNo">382</span>          ((long)cluster.numRegions * (long)this.stepsPerRegion * (long)cluster.numServers));<a name="line.382"></a>
+<span class="sourceLineNo">383</span>    } else {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      long calculatedMaxSteps = (long)cluster.numRegions * (long)this.stepsPerRegion *<a name="line.384"></a>
+<span class="sourceLineNo">385</span>          (long)cluster.numServers;<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      computedMaxSteps = Math.min(this.maxSteps, calculatedMaxSteps);<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      if (calculatedMaxSteps &gt; maxSteps) {<a name="line.387"></a>
+<span class="sourceLineNo">388</span>        LOG.warn("calculatedMaxSteps:{} for loadbalancer's stochastic walk is larger than "<a name="line.388"></a>
+<span class="sourceLineNo">389</span>            + "maxSteps:{}. Hence load balancing may not work well. Setting parameter "<a name="line.389"></a>
+<span class="sourceLineNo">390</span>            + "\"hbase.master.balancer.stochastic.runMaxSteps\" to true can overcome this issue."<a name="line.390"></a>
+<span class="sourceLineNo">391</span>            + "(This config change does not require service restart)", calculatedMaxSteps,<a name="line.391"></a>
+<span class="sourceLineNo">392</span>            maxRunningTime);<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>    LOG.info("start StochasticLoadBalancer.balancer, initCost=" + currentCost + ", functionCost="<a name="line.395"></a>
+<span class="sourceLineNo">396</span>        + functionCost() + " computedMaxSteps: " + computedMaxSteps);<a name="line.396"></a>
+<span class="sourceLineNo">397</span><a name="line.397"></a>
+<span class="sourceLineNo">398</span>    // Perform a stochastic walk to see if we can get a good fit.<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    long step;<a name="line.399"></a>
+<span class="sourceLineNo">400</span><a name="line.400"></a>
+<span class="sourceLineNo">401</span>    for (step = 0; step &lt; computedMaxSteps; step++) {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      Cluster.Action action = nextAction(cluster);<a name="line.402"></a>
+<span class="sourceLineNo">403</span><a name="line.403"></a>
+<span class="sourceLineNo">404</span>      if (action.type == Type.NULL) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>        continue;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      }<a name="line.406"></a>
+<span class="sourceLineNo">407</span><a name="line.407"></a>
+<span class="sourceLineNo">408</span>      cluster.doAction(action);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      updateCostsWithAction(cluster, action);<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>      newCost = computeCost(cluster, currentCost);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>      // Should this be kept?<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      if (newCost &lt; currentCost) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>        currentCost = newCost;<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>        // save for JMX<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        curOverallCost = currentCost;<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        for (int i = 0; i &lt; this.curFunctionCosts.length; i++) {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>          curFunctionCosts[i] = tempFunctionCosts[i];<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        }<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      } else {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Put things back the way they were before.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        // TODO: undo by remembering old values<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        Action undoAction = action.undoAction();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>        cluster.doAction(undoAction);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>        updateCostsWithAction(cluster, undoAction);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>      }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>      if (EnvironmentEdgeManager.currentTime() - startTime &gt;<a name="line.430"></a>
+<span class="sourceLineNo">431</span>          maxRunningTime) {<a name="line.43

<TRUNCATED>