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/07/27 14:51:34 UTC

[01/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Repository: hbase-site
Updated Branches:
  refs/heads/asf-site 23357d7d5 -> 9cc58affb


http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 6c165e5..47095d2 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -667,11 +667,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.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestAtomicOperation.TestStep.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestAtomicOperation.TestStep</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DataBlockEncodingTool.Manipulation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DataBlockEncodingTool.Manipulation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.html b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.html
index 4cdbab6..8773020 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.html
@@ -197,7 +197,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.rsgroup.<a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html" title="class in org.apache.hadoop.hbase.rsgroup">TestRSGroupsBase</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#addGroup-java.lang.String-int-">addGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteGroups--">deleteGroups</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteNamespaceIfNecessary--">deleteNamespaceIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteTableIfNecessary--">deleteTableIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getNumServers--">getNumServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableRegionMap--">getTableRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableServerRegionMap--">getTableServerRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#removeGroup-java.lang.String-">remo
 veGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#setup--">setup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testBogusArgs--">testBogusArgs</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearDeadServers--">testClearDeadServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testDisabledTableMove--">testDisabledTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">t
 estFailRemoveGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersAndTables--">testMoveServersAndTables</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testNonExistentTableMove--">testNonExistentTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#tes
 tRegionMove--">testRegionMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRemoveServers--">testRemoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerMove--">testSimpleRegionServerMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testTableMoveTruncateAndDrop--">testTableMoveTruncateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testValidGroupNames--">testValidGroupNames</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#addGroup-java.lang.String-int-">addGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteGroups--">deleteGroups</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteNamespaceIfNecessary--">deleteNamespaceIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteTableIfNecessary--">deleteTableIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getNumServers--">getNumServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableRegionMap--">getTableRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableServerRegionMap--">getTableServerRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#removeGroup-java.lang.String-">remo
 veGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#setup--">setup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testBogusArgs--">testBogusArgs</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearDeadServers--">testClearDeadServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearNotProcessedDeadServer--">testClearNotProcessedDeadServer</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#test
 DisabledTableMove--">testDisabledTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">testFailRemoveGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersAndTables--">testMoveServersAndTables</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroup
 sBase.html#testNonExistentTableMove--">testNonExistentTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRegionMove--">testRegionMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRemoveServers--">testRemoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerMove--">testSimpleRegionServerMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testTableMoveTruncateAndDrop--">testTableMoveTruncateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testValidGroupNames--">testValidGroupNames</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/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroups.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroups.html b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroups.html
index a7c6fa3..e1b538b 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroups.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroups.html
@@ -302,7 +302,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase
 <!--   -->
 </a>
 <h3>Methods inherited from class&nbsp;org.apache.hadoop.hbase.rsgroup.<a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html" title="class in org.apache.hadoop.hbase.rsgroup">TestRSGroupsBase</a></h3>
-<code><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#addGroup-java.lang.String-int-">addGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteGroups--">deleteGroups</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteNamespaceIfNecessary--">deleteNamespaceIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteTableIfNecessary--">deleteTableIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getNumServers--">getNumServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableRegionMap--">getTableRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableServerRegionMap--">getTableServerRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#removeGroup-java.lang.String-">remo
 veGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#setup--">setup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testBogusArgs--">testBogusArgs</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearDeadServers--">testClearDeadServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testDisabledTableMove--">testDisabledTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">t
 estFailRemoveGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testNonExistentTableMove--">testNonExistentTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRegionMove--">testRegionMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerM
 ove--">testSimpleRegionServerMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testValidGroupNames--">testValidGroupNames</a></code></li>
+<code><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#addGroup-java.lang.String-int-">addGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteGroups--">deleteGroups</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteNamespaceIfNecessary--">deleteNamespaceIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#deleteTableIfNecessary--">deleteTableIfNecessary</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getNumServers--">getNumServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableRegionMap--">getTableRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#getTableServerRegionMap--">getTableServerRegionMap</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#removeGroup-java.lang.String-">remo
 veGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#setup--">setup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testBogusArgs--">testBogusArgs</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearDeadServers--">testClearDeadServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearNotProcessedDeadServer--">testClearNotProcessedDeadServer</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#test
 DisabledTableMove--">testDisabledTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">testFailRemoveGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testNonExistentTableMove--">testNonExistentTableMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroup
 sBase.html#testRegionMove--">testRegionMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerMove--">testSimpleRegionServerMove</a>, <a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testValidGroupNames--">testValidGroupNames</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/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
index b8aeaf0..e4b5612 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.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};
+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};
 var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -272,70 +272,74 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </tr>
 <tr id="i12" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearNotProcessedDeadServer--">testClearNotProcessedDeadServer</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i13" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateAndDrop--">testCreateAndDrop</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i14" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateMultiRegion--">testCreateMultiRegion</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i15" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testDisabledTableMove--">testDisabledTableMove</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testCreateWhenRsgroupNoOnlineServers--">testCreateWhenRsgroupNoOnlineServers</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i16" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">testFailRemoveGroup</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testDisabledTableMove--">testDisabledTableMove</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i17" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testFailRemoveGroup--">testFailRemoveGroup</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i18" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testGroupBalance--">testGroupBalance</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i19" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testKillRS--">testKillRS</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i20" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersAndTables--">testMoveServersAndTables</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServers--">testMoveServers</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i21" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersAndTables--">testMoveServersAndTables</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/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMoveServersFromDefaultGroup--">testMoveServersFromDefaultGroup</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i23" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testNonExistentTableMove--">testNonExistentTableMove</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testMultiTableMove--">testMultiTableMove</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i24" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRegionMove--">testRegionMove</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testNonExistentTableMove--">testNonExistentTableMove</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i25" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRemoveServers--">testRemoveServers</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRegionMove--">testRegionMove</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i26" class="altColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerMove--">testSimpleRegionServerMove</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testRemoveServers--">testRemoveServers</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i27" class="rowColor">
 <td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testTableMoveTruncateAndDrop--">testTableMoveTruncateAndDrop</a></span>()</code>&nbsp;</td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testSimpleRegionServerMove--">testSimpleRegionServerMove</a></span>()</code>&nbsp;</td>
 </tr>
 <tr id="i28" class="altColor">
 <td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testTableMoveTruncateAndDrop--">testTableMoveTruncateAndDrop</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i29" class="rowColor">
+<td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testValidGroupNames--">testValidGroupNames</a></span>()</code>&nbsp;</td>
 </tr>
 </table>
@@ -919,7 +923,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <a name="testCreateWhenRsgroupNoOnlineServers--">
 <!--   -->
 </a>
-<ul class="blockListLast">
+<ul class="blockList">
 <li class="blockList">
 <h4>testCreateWhenRsgroupNoOnlineServers</h4>
 <pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#line.1083">testCreateWhenRsgroupNoOnlineServers</a>()
@@ -930,6 +934,20 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="testClearNotProcessedDeadServer--">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>testClearNotProcessedDeadServer</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#line.1125">testClearNotProcessedDeadServer</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>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
index e23761b..ec4ec49 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
@@ -253,10 +253,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.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadAndVerify.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Generator.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Generator.Counts</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Verify.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Verify.Counts</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadAndVerify.Counters</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 4d091e3..fa9e769 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/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/TestWALSplit.Corruptions.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">TestWALSplit.Corruptions</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/overview-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/overview-tree.html b/testdevapidocs/overview-tree.html
index 635775c..09e3f14 100644
--- a/testdevapidocs/overview-tree.html
+++ b/testdevapidocs/overview-tree.html
@@ -3074,6 +3074,7 @@
 </ul>
 </li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/TestModifyNamespaceProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">TestModifyNamespaceProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestModifyTableWhileMerging</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/TestMovedRegionsCleaner.html" title="class in org.apache.hadoop.hbase"><span class="typeNameLink">TestMovedRegionsCleaner</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.nio.<a href="org/apache/hadoop/hbase/nio/TestMultiByteBuff.html" title="class in org.apache.hadoop.hbase.nio"><span class="typeNameLink">TestMultiByteBuff</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.<a href="org/apache/hadoop/hbase/io/TestMultiByteBuffInputStream.html" title="class in org.apache.hadoop.hbase.io"><span class="typeNameLink">TestMultiByteBuffInputStream</span></a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/serialized-form.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/serialized-form.html b/testdevapidocs/serialized-form.html
index 14c8da7..0d227ff 100644
--- a/testdevapidocs/serialized-form.html
+++ b/testdevapidocs/serialized-form.html
@@ -1348,6 +1348,10 @@
 <!--   -->
 </a>
 <h3>Class org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException extends org.apache.hadoop.hbase.procedure2.ProcedureException implements Serializable</h3>
+<dl class="nameValue">
+<dt>serialVersionUID:</dt>
+<dd>-8328419627678496269L</dd>
+</dl>
 </li>
 <li class="blockList"><a name="org.apache.hadoop.hbase.procedure2.ProcedureYieldException">
 <!--   -->

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
new file mode 100644
index 0000000..fca2ce5
--- /dev/null
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+<title>Source code</title>
+<link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style">
+</head>
+<body>
+<div class="sourceContainer">
+<pre><span class="sourceLineNo">001</span>/**<a name="line.1"></a>
+<span class="sourceLineNo">002</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.2"></a>
+<span class="sourceLineNo">003</span> * or more contributor license agreements.  See the NOTICE file<a name="line.3"></a>
+<span class="sourceLineNo">004</span> * distributed with this work for additional information<a name="line.4"></a>
+<span class="sourceLineNo">005</span> * regarding copyright ownership.  The ASF licenses this file<a name="line.5"></a>
+<span class="sourceLineNo">006</span> * to you under the Apache License, Version 2.0 (the<a name="line.6"></a>
+<span class="sourceLineNo">007</span> * "License"); you may not use this file except in compliance<a name="line.7"></a>
+<span class="sourceLineNo">008</span> * with the License.  You may obtain a copy of the License at<a name="line.8"></a>
+<span class="sourceLineNo">009</span> *<a name="line.9"></a>
+<span class="sourceLineNo">010</span> *     http://www.apache.org/licenses/LICENSE-2.0<a name="line.10"></a>
+<span class="sourceLineNo">011</span> *<a name="line.11"></a>
+<span class="sourceLineNo">012</span> * Unless required by applicable law or agreed to in writing, software<a name="line.12"></a>
+<span class="sourceLineNo">013</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.13"></a>
+<span class="sourceLineNo">014</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.14"></a>
+<span class="sourceLineNo">015</span> * See the License for the specific language governing permissions and<a name="line.15"></a>
+<span class="sourceLineNo">016</span> * limitations under the License.<a name="line.16"></a>
+<span class="sourceLineNo">017</span> */<a name="line.17"></a>
+<span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.master.assignment;<a name="line.18"></a>
+<span class="sourceLineNo">019</span><a name="line.19"></a>
+<span class="sourceLineNo">020</span>import java.util.List;<a name="line.20"></a>
+<span class="sourceLineNo">021</span><a name="line.21"></a>
+<span class="sourceLineNo">022</span>import org.apache.hadoop.hbase.HBaseClassTestRule;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import org.apache.hadoop.hbase.HBaseTestingUtility;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import org.apache.hadoop.hbase.TableName;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.hadoop.hbase.client.Admin;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.client.Table;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.client.TableDescriptor;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureConstants;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.master.procedure.ModifyTableProcedure;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.testclassification.MasterTests;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.testclassification.MediumTests;<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.junit.AfterClass;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.junit.Assert;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.junit.BeforeClass;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.junit.ClassRule;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.junit.Test;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.junit.experimental.categories.Category;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.slf4j.Logger;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.slf4j.LoggerFactory;<a name="line.43"></a>
+<span class="sourceLineNo">044</span><a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;<a name="line.45"></a>
+<span class="sourceLineNo">046</span><a name="line.46"></a>
+<span class="sourceLineNo">047</span><a name="line.47"></a>
+<span class="sourceLineNo">048</span>@Category({MasterTests.class, MediumTests.class})<a name="line.48"></a>
+<span class="sourceLineNo">049</span>public class TestModifyTableWhileMerging {<a name="line.49"></a>
+<span class="sourceLineNo">050</span><a name="line.50"></a>
+<span class="sourceLineNo">051</span>  @ClassRule<a name="line.51"></a>
+<span class="sourceLineNo">052</span>  public static final HBaseClassTestRule CLASS_RULE =<a name="line.52"></a>
+<span class="sourceLineNo">053</span>      HBaseClassTestRule.forClass(TestModifyTableWhileMerging.class);<a name="line.53"></a>
+<span class="sourceLineNo">054</span><a name="line.54"></a>
+<span class="sourceLineNo">055</span>  private static final Logger LOG = LoggerFactory<a name="line.55"></a>
+<span class="sourceLineNo">056</span>      .getLogger(TestModifyTableWhileMerging.class);<a name="line.56"></a>
+<span class="sourceLineNo">057</span><a name="line.57"></a>
+<span class="sourceLineNo">058</span>  protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility();<a name="line.58"></a>
+<span class="sourceLineNo">059</span>  private static TableName TABLE_NAME = TableName.valueOf("test");<a name="line.59"></a>
+<span class="sourceLineNo">060</span>  private static Admin admin;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>  private static Table client;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>  private static byte[] CF = Bytes.toBytes("cf");<a name="line.62"></a>
+<span class="sourceLineNo">063</span>  private static byte[] SPLITKEY = Bytes.toBytes("bbbbbbb");<a name="line.63"></a>
+<span class="sourceLineNo">064</span><a name="line.64"></a>
+<span class="sourceLineNo">065</span>  @BeforeClass<a name="line.65"></a>
+<span class="sourceLineNo">066</span>  public static void setupCluster() throws Exception {<a name="line.66"></a>
+<span class="sourceLineNo">067</span>    //Set procedure executor thread to 1, making reproducing this issue of HBASE-20921 easier<a name="line.67"></a>
+<span class="sourceLineNo">068</span>    UTIL.getConfiguration().setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1);<a name="line.68"></a>
+<span class="sourceLineNo">069</span>    UTIL.startMiniCluster(1);<a name="line.69"></a>
+<span class="sourceLineNo">070</span>    admin = UTIL.getHBaseAdmin();<a name="line.70"></a>
+<span class="sourceLineNo">071</span>    byte[][] splitKeys = new byte[1][];<a name="line.71"></a>
+<span class="sourceLineNo">072</span>    splitKeys[0] = SPLITKEY;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    client = UTIL.createTable(TABLE_NAME, CF, splitKeys);<a name="line.73"></a>
+<span class="sourceLineNo">074</span>    UTIL.waitTableAvailable(TABLE_NAME);<a name="line.74"></a>
+<span class="sourceLineNo">075</span>  }<a name="line.75"></a>
+<span class="sourceLineNo">076</span><a name="line.76"></a>
+<span class="sourceLineNo">077</span>  @AfterClass<a name="line.77"></a>
+<span class="sourceLineNo">078</span>  public static void cleanupTest() throws Exception {<a name="line.78"></a>
+<span class="sourceLineNo">079</span>    try {<a name="line.79"></a>
+<span class="sourceLineNo">080</span>      UTIL.shutdownMiniCluster();<a name="line.80"></a>
+<span class="sourceLineNo">081</span>    } catch (Exception e) {<a name="line.81"></a>
+<span class="sourceLineNo">082</span>      LOG.warn("failure shutting down cluster", e);<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><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  @Test<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public void test() throws Exception {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    TableDescriptor tableDescriptor = client.getDescriptor();<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    ProcedureExecutor&lt;MasterProcedureEnv&gt; executor = UTIL.getMiniHBaseCluster().getMaster()<a name="line.89"></a>
+<span class="sourceLineNo">090</span>        .getMasterProcedureExecutor();<a name="line.90"></a>
+<span class="sourceLineNo">091</span>    MasterProcedureEnv env = executor.getEnvironment();<a name="line.91"></a>
+<span class="sourceLineNo">092</span>    List&lt;RegionInfo&gt; regionInfos = admin.getRegions(TABLE_NAME);<a name="line.92"></a>
+<span class="sourceLineNo">093</span>    MergeTableRegionsProcedure mergeTableRegionsProcedure = new MergeTableRegionsProcedure(<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      UTIL.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor()<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        .getEnvironment(), regionInfos.get(0), regionInfos.get(1));<a name="line.95"></a>
+<span class="sourceLineNo">096</span>    ModifyTableProcedure modifyTableProcedure = new ModifyTableProcedure(env, tableDescriptor);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>    long procModify = executor.submitProcedure(modifyTableProcedure);<a name="line.97"></a>
+<span class="sourceLineNo">098</span>    UTIL.waitFor(30000, () -&gt; executor.getProcedures().stream()<a name="line.98"></a>
+<span class="sourceLineNo">099</span>      .filter(p -&gt; p instanceof ModifyTableProcedure)<a name="line.99"></a>
+<span class="sourceLineNo">100</span>      .map(p -&gt; (ModifyTableProcedure) p)<a name="line.100"></a>
+<span class="sourceLineNo">101</span>      .anyMatch(p -&gt; TABLE_NAME.equals(p.getTableName())));<a name="line.101"></a>
+<span class="sourceLineNo">102</span>    long proc = executor.submitProcedure(mergeTableRegionsProcedure);<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    UTIL.waitFor(3000000, () -&gt; UTIL.getMiniHBaseCluster().getMaster()<a name="line.103"></a>
+<span class="sourceLineNo">104</span>        .getMasterProcedureExecutor().isFinished(procModify));<a name="line.104"></a>
+<span class="sourceLineNo">105</span>    Assert.assertEquals("Modify Table procedure should success!",<a name="line.105"></a>
+<span class="sourceLineNo">106</span>        ProcedureProtos.ProcedureState.SUCCESS, modifyTableProcedure.getState());<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  }<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>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</pre>
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
index ef9f492..51b3825 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html
@@ -1129,7 +1129,35 @@
 <span class="sourceLineNo">1121</span>      }<a name="line.1121"></a>
 <span class="sourceLineNo">1122</span>    });<a name="line.1122"></a>
 <span class="sourceLineNo">1123</span>  }<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>}<a name="line.1124"></a>
+<span class="sourceLineNo">1124</span>  @Test<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>  public void testClearNotProcessedDeadServer() throws Exception {<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>    LOG.info("testClearNotProcessedDeadServer");<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>    NUM_DEAD_SERVERS = cluster.getClusterMetrics().getDeadServerNames().size();<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>    RSGroupInfo appInfo = addGroup("deadServerGroup", 1);<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>    ServerName targetServer =<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>        ServerName.parseServerName(appInfo.getServers().iterator().next().toString());<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>    AdminProtos.AdminService.BlockingInterface targetRS =<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>        ((ClusterConnection) admin.getConnection()).getAdmin(targetServer);<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>    try {<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>      targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null,<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>          AdminProtos.GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName());<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>      //stopping may cause an exception<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>      //due to the connection loss<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>      targetRS.stopServer(null,<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>          AdminProtos.StopServerRequest.newBuilder().setReason("Die").build());<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>      NUM_DEAD_SERVERS ++;<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>    } catch(Exception e) {<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>    }<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate&lt;Exception&gt;() {<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      @Override<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>      public boolean evaluate() throws Exception {<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>        return cluster.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS;<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>      }<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    });<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>    List&lt;ServerName&gt; notClearedServers = admin.clearDeadServers(Lists.newArrayList(targetServer));<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>    assertEquals(1, notClearedServers.size());<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>  }<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>}<a name="line.1152"></a>
 
 
 


[07/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>          parent.incC

<TRUNCATED>

[10/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line.482"></a>
-<span class="sourc

<TRUNCATED>

[27/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/checkstyle-aggregate.html
----------------------------------------------------------------------
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 35105b3..fe45785 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Checkstyle Results</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -281,10 +281,10 @@
 <th><img src="images/icon_warning_sml.gif" alt="" />&#160;Warnings</th>
 <th><img src="images/icon_error_sml.gif" alt="" />&#160;Errors</th></tr>
 <tr class="b">
-<td>3695</td>
+<td>3696</td>
 <td>0</td>
 <td>0</td>
-<td>15633</td></tr></table></div>
+<td>15632</td></tr></table></div>
 <div class="section">
 <h2><a name="Files"></a>Files</h2>
 <table border="0" class="table table-striped">
@@ -9209,596 +9209,591 @@
 <td>0</td>
 <td>2</td></tr>
 <tr class="a">
-<td><a href="#org.apache.hadoop.hbase.util.IdLock.java">org/apache/hadoop/hbase/util/IdLock.java</a></td>
-<td>0</td>
-<td>0</td>
-<td>1</td></tr>
-<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.IdReadWriteLock.java">org/apache/hadoop/hbase/util/IdReadWriteLock.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>6</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.JSONBean.java">org/apache/hadoop/hbase/util/JSONBean.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>16</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.JSONMetricUtil.java">org/apache/hadoop/hbase/util/JSONMetricUtil.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.JVM.java">org/apache/hadoop/hbase/util/JVM.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.JVMClusterUtil.java">org/apache/hadoop/hbase/util/JVMClusterUtil.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>11</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.JenkinsHash.java">org/apache/hadoop/hbase/util/JenkinsHash.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>38</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.JsonMapper.java">org/apache/hadoop/hbase/util/JsonMapper.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.JvmPauseMonitor.java">org/apache/hadoop/hbase/util/JvmPauseMonitor.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.KeyLocker.java">org/apache/hadoop/hbase/util/KeyLocker.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>6</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.LoadTestDataGeneratorWithMOB.java">org/apache/hadoop/hbase/util/LoadTestDataGeneratorWithMOB.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.LoadTestDataGeneratorWithTags.java">org/apache/hadoop/hbase/util/LoadTestDataGeneratorWithTags.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.LoadTestTool.java">org/apache/hadoop/hbase/util/LoadTestTool.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MD5Hash.java">org/apache/hadoop/hbase/util/MD5Hash.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ManualEnvironmentEdge.java">org/apache/hadoop/hbase/util/ManualEnvironmentEdge.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MapreduceDependencyClasspathTool.java">org/apache/hadoop/hbase/util/MapreduceDependencyClasspathTool.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.Methods.java">org/apache/hadoop/hbase/util/Methods.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MockServer.java">org/apache/hadoop/hbase/util/MockServer.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ModifyRegionUtils.java">org/apache/hadoop/hbase/util/ModifyRegionUtils.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>8</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MultiHConnection.java">org/apache/hadoop/hbase/util/MultiHConnection.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedAction.java">org/apache/hadoop/hbase/util/MultiThreadedAction.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>9</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedReader.java">org/apache/hadoop/hbase/util/MultiThreadedReader.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedReaderWithACL.java">org/apache/hadoop/hbase/util/MultiThreadedReaderWithACL.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedUpdater.java">org/apache/hadoop/hbase/util/MultiThreadedUpdater.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>19</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedWriter.java">org/apache/hadoop/hbase/util/MultiThreadedWriter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MultiThreadedWriterBase.java">org/apache/hadoop/hbase/util/MultiThreadedWriterBase.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.MunkresAssignment.java">org/apache/hadoop/hbase/util/MunkresAssignment.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.MurmurHash3.java">org/apache/hadoop/hbase/util/MurmurHash3.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>11</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig.java">org/apache/hadoop/hbase/util/NettyEventLoopGroupConfig.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Order.java">org/apache/hadoop/hbase/util/Order.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>8</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.OrderedBytes.java">org/apache/hadoop/hbase/util/OrderedBytes.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>44</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Pair.java">org/apache/hadoop/hbase/util/Pair.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>16</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.PairOfSameType.java">org/apache/hadoop/hbase/util/PairOfSameType.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>8</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.PoolMap.java">org/apache/hadoop/hbase/util/PoolMap.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>8</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.PositionedByteRange.java">org/apache/hadoop/hbase/util/PositionedByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.PrettyPrinter.java">org/apache/hadoop/hbase/util/PrettyPrinter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ProcessBasedLocalHBaseCluster.java">org/apache/hadoop/hbase/util/ProcessBasedLocalHBaseCluster.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.RedundantKVGenerator.java">org/apache/hadoop/hbase/util/RedundantKVGenerator.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ReflectionUtils.java">org/apache/hadoop/hbase/util/ReflectionUtils.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.RegionMover.java">org/apache/hadoop/hbase/util/RegionMover.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>35</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.RegionSplitCalculator.java">org/apache/hadoop/hbase/util/RegionSplitCalculator.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>6</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.RegionSplitter.java">org/apache/hadoop/hbase/util/RegionSplitter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>17</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.RetryCounter.java">org/apache/hadoop/hbase/util/RetryCounter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.RollingStatCalculator.java">org/apache/hadoop/hbase/util/RollingStatCalculator.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.RowBloomContext.java">org/apache/hadoop/hbase/util/RowBloomContext.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.ServerCommandLine.java">org/apache/hadoop/hbase/util/ServerCommandLine.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ServerRegionReplicaUtil.java">org/apache/hadoop/hbase/util/ServerRegionReplicaUtil.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.ShutdownHookManager.java">org/apache/hadoop/hbase/util/ShutdownHookManager.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.SimpleByteRange.java">org/apache/hadoop/hbase/util/SimpleByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.SimpleMutableByteRange.java">org/apache/hadoop/hbase/util/SimpleMutableByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.SimplePositionedByteRange.java">org/apache/hadoop/hbase/util/SimplePositionedByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.SimplePositionedMutableByteRange.java">org/apache/hadoop/hbase/util/SimplePositionedMutableByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.Sleeper.java">org/apache/hadoop/hbase/util/Sleeper.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.StealJobQueue.java">org/apache/hadoop/hbase/util/StealJobQueue.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.StoppableImplementation.java">org/apache/hadoop/hbase/util/StoppableImplementation.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Strings.java">org/apache/hadoop/hbase/util/Strings.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestBloomFilterChunk.java">org/apache/hadoop/hbase/util/TestBloomFilterChunk.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestBytes.java">org/apache/hadoop/hbase/util/TestBytes.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>22</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestCompressionTest.java">org/apache/hadoop/hbase/util/TestCompressionTest.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>12</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestCoprocessorClassLoader.java">org/apache/hadoop/hbase/util/TestCoprocessorClassLoader.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestCoprocessorScanPolicy.java">org/apache/hadoop/hbase/util/TestCoprocessorScanPolicy.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestFSTableDescriptors.java">org/apache/hadoop/hbase/util/TestFSTableDescriptors.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>11</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestFSUtils.java">org/apache/hadoop/hbase/util/TestFSUtils.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>7</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestFSVisitor.java">org/apache/hadoop/hbase/util/TestFSVisitor.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestHFileArchiveUtil.java">org/apache/hadoop/hbase/util/TestHFileArchiveUtil.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestIdLock.java">org/apache/hadoop/hbase/util/TestIdLock.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestIdReadWriteLock.java">org/apache/hadoop/hbase/util/TestIdReadWriteLock.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>10</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestMiniClusterLoadEncoded.java">org/apache/hadoop/hbase/util/TestMiniClusterLoadEncoded.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestMiniClusterLoadSequential.java">org/apache/hadoop/hbase/util/TestMiniClusterLoadSequential.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestOrderedBytes.java">org/apache/hadoop/hbase/util/TestOrderedBytes.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>30</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestRegionSplitter.java">org/apache/hadoop/hbase/util/TestRegionSplitter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>192</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.TestSimplePositionedMutableByteRange.java">org/apache/hadoop/hbase/util/TestSimplePositionedMutableByteRange.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TestSortedList.java">org/apache/hadoop/hbase/util/TestSortedList.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Threads.java">org/apache/hadoop/hbase/util/Threads.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>6</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.TimeOffsetEnvironmentEdge.java">org/apache/hadoop/hbase/util/TimeOffsetEnvironmentEdge.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Triple.java">org/apache/hadoop/hbase/util/Triple.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.UnsafeAccess.java">org/apache/hadoop/hbase/util/UnsafeAccess.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>35</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.UnsafeAvailChecker.java">org/apache/hadoop/hbase/util/UnsafeAvailChecker.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.VersionInfo.java">org/apache/hadoop/hbase/util/VersionInfo.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.Writables.java">org/apache/hadoop/hbase/util/Writables.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>14</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.ZKDataMigrator.java">org/apache/hadoop/hbase/util/ZKDataMigrator.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>18</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.compaction.MajorCompactor.java">org/apache/hadoop/hbase/util/compaction/MajorCompactor.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.compaction.TestMajorCompactionRequest.java">org/apache/hadoop/hbase/util/compaction/TestMajorCompactionRequest.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.compaction.TestMajorCompactor.java">org/apache/hadoop/hbase/util/compaction/TestMajorCompactor.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.hbck.HFileCorruptionChecker.java">org/apache/hadoop/hbase/util/hbck/HFileCorruptionChecker.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>10</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.java">org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.hbck.OfflineMetaRebuildTestCore.java">org/apache/hadoop/hbase/util/hbck/OfflineMetaRebuildTestCore.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.hbck.OfflineMetaRepair.java">org/apache/hadoop/hbase/util/hbck/OfflineMetaRepair.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.util.test.LoadTestDataGenerator.java">org/apache/hadoop/hbase/util/test/LoadTestDataGenerator.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>8</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.util.test.LoadTestDataGeneratorWithACL.java">org/apache/hadoop/hbase/util/test/LoadTestDataGeneratorWithACL.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.AbstractFSWALProvider.java">org/apache/hadoop/hbase/wal/AbstractFSWALProvider.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.BoundedGroupingStrategy.java">org/apache/hadoop/hbase/wal/BoundedGroupingStrategy.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.DisabledWALProvider.java">org/apache/hadoop/hbase/wal/DisabledWALProvider.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.FSHLogProvider.java">org/apache/hadoop/hbase/wal/FSHLogProvider.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.IOTestProvider.java">org/apache/hadoop/hbase/wal/IOTestProvider.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.NamespaceGroupingStrategy.java">org/apache/hadoop/hbase/wal/NamespaceGroupingStrategy.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.NettyAsyncFSWALConfigHelper.java">org/apache/hadoop/hbase/wal/NettyAsyncFSWALConfigHelper.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.TestBoundedRegionGroupingStrategy.java">org/apache/hadoop/hbase/wal/TestBoundedRegionGroupingStrategy.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.TestFSHLogProvider.java">org/apache/hadoop/hbase/wal/TestFSHLogProvider.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>5</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALFactory.java">org/apache/hadoop/hbase/wal/TestWALFactory.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>19</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALFiltering.java">org/apache/hadoop/hbase/wal/TestWALFiltering.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>4</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALMethods.java">org/apache/hadoop/hbase/wal/TestWALMethods.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>2</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALOpenAfterDNRollingStart.java">org/apache/hadoop/hbase/wal/TestWALOpenAfterDNRollingStart.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALReaderOnSecureWAL.java">org/apache/hadoop/hbase/wal/TestWALReaderOnSecureWAL.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALRootDir.java">org/apache/hadoop/hbase/wal/TestWALRootDir.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.TestWALSplit.java">org/apache/hadoop/hbase/wal/TestWALSplit.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>16</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.WAL.java">org/apache/hadoop/hbase/wal/WAL.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>16</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.WALEdit.java">org/apache/hadoop/hbase/wal/WALEdit.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.WALFactory.java">org/apache/hadoop/hbase/wal/WALFactory.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.WALKey.java">org/apache/hadoop/hbase/wal/WALKey.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.WALKeyImpl.java">org/apache/hadoop/hbase/wal/WALKeyImpl.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>7</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.WALPerformanceEvaluation.java">org/apache/hadoop/hbase/wal/WALPerformanceEvaluation.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>12</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.wal.WALPrettyPrinter.java">org/apache/hadoop/hbase/wal/WALPrettyPrinter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>17</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.wal.WALSplitter.java">org/apache/hadoop/hbase/wal/WALSplitter.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>41</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient.java">org/apache/hadoop/hbase/zookeeper/ReadOnlyZKClient.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.zookeeper.ZKConfig.java">org/apache/hadoop/hbase/zookeeper/ZKConfig.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>3</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.zookeeper.ZKMetadata.java">org/apache/hadoop/hbase/zookeeper/ZKMetadata.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>1</td></tr>
-<tr class="b">
+<tr class="a">
 <td><a href="#org.apache.hadoop.hbase.zookeeper.ZNodePaths.java">org/apache/hadoop/hbase/zookeeper/ZNodePaths.java</a></td>
 <td>0</td>
 <td>0</td>
 <td>26</td></tr>
-<tr class="a">
+<tr class="b">
 <td><a href="#org.apache.hadoop.hbase.zookeeper.ZooKeeperHelper.java">org/apache/hadoop/hbase/zookeeper/ZooKeeperHelper.java</a></td>
 <td>0</td>
 <td>0</td>
@@ -9806,67 +9801,67 @@
 <div class="section">
 <h2><a name="Rules"></a>Rules</h2>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Category</th>
 <th>Rule</th>
 <th>Violations</th>
 <th>Severity</th></tr>
-<tr class="a">
+<tr class="b">
 <td>annotation</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_annotation.html#MissingDeprecated">MissingDeprecated</a></td>
 <td>141</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>blocks</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_blocks.html#EmptyBlock">EmptyBlock</a></td>
 <td>44</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_blocks.html#LeftCurly">LeftCurly</a></td>
 <td>194</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_blocks.html#NeedBraces">NeedBraces</a></td>
 <td>1851</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td>coding</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_coding.html#EmptyStatement">EmptyStatement</a></td>
 <td>31</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_coding.html#EqualsHashCode">EqualsHashCode</a></td>
 <td>4</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_coding.html#InnerAssignment">InnerAssignment</a></td>
 <td>92</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_coding.html#NoFinalizer">NoFinalizer</a></td>
 <td>1</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td>design</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_design.html#FinalClass">FinalClass</a></td>
-<td>54</td>
+<td>53</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_design.html#HideUtilityClassConstructor">HideUtilityClassConstructor</a></td>
 <td>98</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_design.html#InterfaceIsType">InterfaceIsType</a></td>
 <td>1</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_design.html#VisibilityModifier">VisibilityModifier</a>
 <ul>
@@ -9875,12 +9870,12 @@
 <li>allowPublicImmutableFields: <tt>&quot;true&quot;</tt></li></ul></td>
 <td>124</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td>imports</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_imports.html#AvoidStarImport">AvoidStarImport</a></td>
 <td>79</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_imports.html#ImportOrder">ImportOrder</a>
 <ul>
@@ -9890,19 +9885,19 @@
 <li>option: <tt>&quot;top&quot;</tt></li></ul></td>
 <td>1156</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_imports.html#RedundantImport">RedundantImport</a></td>
 <td>26</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_imports.html#UnusedImports">UnusedImports</a>
 <ul>
 <li>processJavadoc: <tt>&quot;true&quot;</tt></li></ul></td>
 <td>113</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td>indentation</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_indentation.html#Indentation">Indentation</a>
 <ul>
@@ -9913,29 +9908,29 @@
 <li>lineWrappingIndentation: <tt>&quot;2&quot;</tt></li></ul></td>
 <td>4989</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>javadoc</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#JavadocTagContinuationIndentation">JavadocTagContinuationIndentation</a>
 <ul>
 <li>offset: <tt>&quot;2&quot;</tt></li></ul></td>
 <td>770</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#NonEmptyAtclauseDescription">NonEmptyAtclauseDescription</a></td>
 <td>3644</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>misc</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_misc.html#ArrayTypeStyle">ArrayTypeStyle</a></td>
 <td>148</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_misc.html#UpperEll">UpperEll</a></td>
 <td>44</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>sizes</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_sizes.html#LineLength">LineLength</a>
 <ul>
@@ -9943,22 +9938,22 @@
 <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>1524</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_sizes.html#MethodLength">MethodLength</a></td>
 <td>68</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>whitespace</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_whitespace.html#FileTabCharacter">FileTabCharacter</a></td>
 <td>9</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_whitespace.html#MethodParamPad">MethodParamPad</a></td>
 <td>167</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_whitespace.html#ParenPad">ParenPad</a></td>
 <td>261</td>
@@ -9968,49 +9963,49 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.AcidGuaranteesTestTool.java">org/apache/hadoop/hbase/AcidGuaranteesTestTool.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>138</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>163</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>215</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>216</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>282</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
 <td>Array brackets at illegal position.</td>
 <td>283</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>misc</td>
 <td>ArrayTypeStyle</td>
@@ -10019,157 +10014,157 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.AsyncMetaTableAccessor.java">org/apache/hadoop/hbase/AsyncMetaTableAccessor.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>design</td>
 <td>HideUtilityClassConstructor</td>
 <td>Utility classes should not have a public or default constructor.</td>
 <td>62</td></tr>
-<tr class="a">
+<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>109</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'lambda arguments' has incorrect indentation level 8, expected level should be 14.</td>
 <td>121</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if' has incorrect indentation level 10, expected level should be 16.</td>
 <td>122</td></tr>
-<tr class="b">
+<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 12, expected level should be 18.</td>
 <td>123</td></tr>
-<tr class="a">
+<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 18.</td>
 <td>124</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'if rcurly' has incorrect indentation level 10, expected level should be 16.</td>
 <td>125</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'block' child has incorrect indentation level 10, expected level should be 16.</td>
 <td>126</td></tr>
-<tr class="b">
+<tr class="a">
 <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 8, expected level should be 14.</td>
 <td>128</td></tr>
-<tr class="a">
+<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>138</td></tr>
-<tr class="b">
+<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>178</td></tr>
-<tr class="a">
+<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>191</td></tr>
-<tr class="b">
+<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>217</td></tr>
-<tr class="a">
+<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 117).</td>
 <td>233</td></tr>
-<tr class="b">
+<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>244</td></tr>
-<tr class="a">
+<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>275</td></tr>
-<tr class="b">
+<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>288</td></tr>
-<tr class="a">
+<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>394</td></tr>
-<tr class="b">
+<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>396</td></tr>
-<tr class="a">
+<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>404</td></tr>
-<tr class="b">
+<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>412</td></tr>
-<tr class="a">
+<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>457</td></tr>
-<tr class="b">
+<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>462</td></tr>
-<tr class="a">
+<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>480</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -10178,19 +10173,19 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.AuthUtil.java">org/apache/hadoop/hbase/AuthUtil.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>design</td>
 <td>FinalClass</td>
 <td>Class AuthUtil should be declared as final.</td>
 <td>69</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -10199,13 +10194,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.BBKVComparator.java">org/apache/hadoop/hbase/BBKVComparator.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
@@ -10214,25 +10209,25 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue.java">org/apache/hadoop/hbase/ByteBufferKeyOnlyKeyValue.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<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>59</td></tr>
-<tr class="b">
+<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>60</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -10241,13 +10236,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.Cell.java">org/apache/hadoop/hbase/Cell.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>JavadocTagContinuationIndentation</td>
@@ -10256,31 +10251,31 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CellBuilderFactory.java">org/apache/hadoop/hbase/CellBuilderFactory.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 109).</td>
 <td>25</td></tr>
-<tr class="b">
+<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 107).</td>
 <td>27</td></tr>
-<tr class="a">
+<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 113).</td>
 <td>28</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
@@ -10289,13 +10284,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CellComparator.java">org/apache/hadoop/hbase/CellComparator.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>JavadocTagContinuationIndentation</td>
@@ -10304,13 +10299,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CellComparatorImpl.java">org/apache/hadoop/hbase/CellComparatorImpl.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
@@ -10319,13 +10314,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CellScanner.java">org/apache/hadoop/hbase/CellScanner.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -10334,409 +10329,409 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CellUtil.java">org/apache/hadoop/hbase/CellUtil.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<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>143</td></tr>
-<tr class="a">
+<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>156</td></tr>
-<tr class="b">
+<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>157</td></tr>
-<tr class="a">
+<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>376</td></tr>
-<tr class="b">
+<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>377</td></tr>
-<tr class="a">
+<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>378</td></tr>
-<tr class="b">
+<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>389</td></tr>
-<tr class="a">
+<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>390</td></tr>
-<tr class="b">
+<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>391</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>annotation</td>
 <td>MissingDeprecated</td>
 <td>Must include both @java.lang.Deprecated annotation and @deprecated Javadoc tag with description.</td>
 <td>402</td></tr>
-<tr class="b">
+<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>420</td></tr>
-<tr class="a">
+<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>522</td></tr>
-<tr class="b">
+<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>534</td></tr>
-<tr class="a">
+<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>535</td></tr>
-<tr class="b">
+<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>552</td></tr>
-<tr class="a">
+<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>553</td></tr>
-<tr class="b">
+<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>554</td></tr>
-<tr class="a">
+<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>597</td></tr>
-<tr class="b">
+<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>615</td></tr>
-<tr class="a">
+<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>618</td></tr>
-<tr class="b">
+<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>626</td></tr>
-<tr class="a">
+<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>630</td></tr>
-<tr class="b">
+<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>635</td></tr>
-<tr class="a">
+<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>637</td></tr>
-<tr class="b">
+<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>640</td></tr>
-<tr class="a">
+<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>660</td></tr>
-<tr class="b">
+<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>670</td></tr>
-<tr class="a">
+<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>676</td></tr>
-<tr class="b">
+<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>685</td></tr>
-<tr class="a">
+<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>703</td></tr>
-<tr class="b">
+<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>718</td></tr>
-<tr class="a">
+<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>719</td></tr>
-<tr class="b">
+<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>816</td></tr>
-<tr class="a">
+<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>830</td></tr>
-<tr class="b">
+<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>844</td></tr>
-<tr class="a">
+<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>859</td></tr>
-<tr class="b">
+<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>986</td></tr>
-<tr class="a">
+<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>1013</td></tr>
-<tr class="b">
+<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>1026</td></tr>
-<tr class="a">
+<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>1027</td></tr>
-<tr class="b">
+<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>1028</td></tr>
-<tr class="a">
+<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>1107</td></tr>
-<tr class="b">
+<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>1108</td></tr>
-<tr class="a">
+<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>1119</td></tr>
-<tr class="b">
+<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>1120</td></tr>
-<tr class="a">
+<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>1131</td></tr>
-<tr class="b">
+<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>1145</td></tr>
-<tr class="a">
+<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>1146</td></tr>
-<tr class="b">
+<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>1159</td></tr>
-<tr class="a">
+<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>1185</td></tr>
-<tr class="b">
+<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>1199</td></tr>
-<tr class="a">
+<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>1217</td></tr>
-<tr class="b">
+<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>1227</td></tr>
-<tr class="a">
+<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>1248</td></tr>
-<tr class="b">
+<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>1250</td></tr>
-<tr class="a">
+<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>1260</td></tr>
-<tr class="b">
+<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>1261</td></tr>
-<tr class="a">
+<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>1262</td></tr>
-<tr class="b">
+<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>1263</td></tr>
-<tr class="a">
+<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>1264</td></tr>
-<tr class="b">
+<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>1355</td></tr>
-<tr class="a">
+<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>1356</td></tr>
-<tr class="b">
+<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>1362</td></tr>
-<tr class="a">
+<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>1385</td></tr>
-<tr class="b">
+<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>1386</td></tr>
-<tr class="a">
+<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>1471</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -10745,31 +10740,31 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ChoreService.java">org/apache/hadoop/hbase/ChoreService.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<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>172</td></tr>
-<tr class="a">
+<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>302</td></tr>
-<tr class="b">
+<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>374</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -10778,31 +10773,31 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ClassFinder.java">org/apache/hadoop/hbase/ClassFinder.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>LeftCurly</td>
 <td>'{' at column 54 should have line break after.</td>
 <td>70</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>LeftCurly</td>
 <td>'{' at column 46 should have line break after.</td>
 <td>71</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>LeftCurly</td>
 <td>'{' at column 40 should have line break after.</td>
 <td>72</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>LeftCurly</td>
@@ -10811,31 +10806,31 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ClusterId.java">org/apache/hadoop/hbase/ClusterId.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'org.apache.hadoop.hbase.exceptions.DeserializationException' import.</td>
 <td>25</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'org.apache.hadoop.hbase.util.Bytes' import.</td>
 <td>28</td></tr>
-<tr class="b">
+<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>60</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -10844,13 +10839,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ClusterManager.java">org/apache/hadoop/hbase/ClusterManager.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
@@ -10859,13 +10854,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ClusterStatus.java">org/apache/hadoop/hbase/ClusterStatus.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -10874,37 +10869,37 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CompoundConfiguration.java">org/apache/hadoop/hbase/CompoundConfiguration.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'member def modifier' has incorrect indentation level 3, expected level should be 4.</td>
 <td>79</td></tr>
-<tr class="b">
+<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>183</td></tr>
-<tr class="a">
+<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>186</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'throws' has incorrect indentation level 6, expected level should be 8.</td>
 <td>198</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
@@ -10913,13 +10908,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.CoordinatedStateManager.java">org/apache/hadoop/hbase/CoordinatedStateManager.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
@@ -10928,19 +10923,19 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.Coprocessor.java">org/apache/hadoop/hbase/Coprocessor.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'com.google.protobuf.Service' import.</td>
 <td>25</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>JavadocTagContinuationIndentation</td>
@@ -10949,43 +10944,43 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.DistributedHBaseCluster.java">org/apache/hadoop/hbase/DistributedHBaseCluster.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<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>81</td></tr>
-<tr class="a">
+<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>105</td></tr>
-<tr class="b">
+<tr class="a">
 <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>111</td></tr>
-<tr class="a">
+<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>238</td></tr>
-<tr class="b">
+<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>438</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -10994,25 +10989,25 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.DoNotRetryIOException.java">org/apache/hadoop/hbase/DoNotRetryIOException.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<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>40</td></tr>
-<tr class="b">
+<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>47</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11021,13 +11016,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.DroppedSnapshotException.java">org/apache/hadoop/hbase/DroppedSnapshotException.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11036,13 +11031,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.ExtendedCell.java">org/apache/hadoop/hbase/ExtendedCell.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11051,19 +11046,19 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.GenericTestUtils.java">org/apache/hadoop/hbase/GenericTestUtils.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>LeftCurly</td>
 <td>'{' at column 3 should be on the previous line.</td>
 <td>99</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -11072,13 +11067,13 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseClassTestRuleChecker.java">org/apache/hadoop/hbase/HBaseClassTestRuleChecker.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>UnusedImports</td>
@@ -11087,43 +11082,43 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseCluster.java">org/apache/hadoop/hbase/HBaseCluster.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <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>102</td></tr>
-<tr class="a">
+<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>108</td></tr>
-<tr class="b">
+<tr class="a">
 <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>114</td></tr>
-<tr class="a">
+<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>349</td></tr>
-<tr class="b">
+<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>353</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11132,19 +11127,19 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseClusterManager.java">org/apache/hadoop/hbase/HBaseClusterManager.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<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 104).</td>
 <td>68</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
@@ -11153,85 +11148,85 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseCommonTestingUtility.java">org/apache/hadoop/hbase/HBaseCommonTestingUtility.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'array initialization' child has incorrect indentation level 6, expected level should be 4.</td>
 <td>61</td></tr>
-<tr class="a">
+<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>101</td></tr>
-<tr class="b">
+<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>102</td></tr>
-<tr class="a">
+<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>112</td></tr>
-<tr class="b">
+<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>115</td></tr>
-<tr class="a">
+<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>136</td></tr>
-<tr class="b">
+<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>160</td></tr>
-<tr class="a">
+<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>175</td></tr>
-<tr class="b">
+<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>188</td></tr>
-<tr class="a">
+<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>200</td></tr>
-<tr class="b">
+<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>201</td></tr>
-<tr class="a">
+<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>214</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
@@ -11240,43 +11235,43 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseConfiguration.java">org/apache/hadoop/hbase/HBaseConfiguration.java</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<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>66</td></tr>
-<tr class="a">
+<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>100</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'catch' child has incorrect indentation level 7, expected level should be 6.</td>
 <td>164</td></tr>
-<tr class="a">
+<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>181</td></tr>
-<tr class="b">
+<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>210</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11285,157 +11280,157 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseTestCase.java">org/apache/hadoop/hbase/HBaseTestCase.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>imports</td>
 <td>ImportOrder</td>
 <td>Wrong order for 'junit.framework.AssertionFailedError' import.</td>
 <td>44</td></tr>
-<tr class="b">
+<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>91</td></tr>
-<tr class="a">
+<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>141</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method def modifier' has incorrect indentation level 4, expected level should be 2.</td>
 <td>144</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method def' child has incorrect indentation level 6, expected level should be 4.</td>
 <td>145</td></tr>
-<tr class="b">
+<tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method def rcurly' has incorrect indentation level 4, expected level should be 2.</td>
 <td>146</td></tr>
-<tr class="a">
+<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>151</td></tr>
-<tr class="b">
+<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>152</td></tr>
-<tr class="a">
+<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>153</td></tr>
-<tr class="b">
+<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>155</td></tr>
-<tr class="a">
+<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>159</td></tr>
-<tr class="b">
+<tr class="a">
 <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>165</td></tr>
-<tr class="a">
+<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>171</td></tr>
-<tr class="b">
+<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>
-<tr class="a">
+<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>225</td></tr>
-<tr class="b">
+<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>226</td></tr>
-<tr class="a">
+<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>227</td></tr>
-<tr class="b">
+<tr class="a">
 <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>231</td></tr>
-<tr class="a">
+<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>250</td></tr>
-<tr class="b">
+<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>268</td></tr>
-<tr class="a">
+<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>272</td></tr>
-<tr class="b">
+<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>286</td></tr>
-<tr class="a">
+<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>292</td></tr>
-<tr class="b">
+<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>394</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
@@ -11444,1663 +11439,1663 @@
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.HBaseTestingUtility.java">org/apache/hadoop/hbase/HBaseTestingUtility.java</h3>
 <table border="0" class="table table-striped">
-<tr class="b">
+<tr class="a">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="a">
+<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>384</td></tr>
-<tr class="b">
+<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>386</td></tr>
-<tr class="a">
+<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 7, expected level should be 8.</td>
 <td>463</td></tr>
-<tr class="b">
+<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 9, expected level should be 10.</td>
 <td>464</td></tr>
-<tr class="a">
+<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 9, expected level should be 10.</td>
 <td>465</td></tr>
-<tr class="b">
+<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 9, expected level should be 10.</td>
 <td>466</td></tr>
-<tr class="a">
+<tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>indentation</td>
 <td>Indentation</td>
 <td>'method call rparen' has incorrect indentation level 7, expected level should be 8.</td>
 <td>467</td></tr>
-<tr class="b">
+<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>479</td></tr>
-<tr class="a">
+<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>561</td></tr>
-<tr class="b">
+<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>565</td></tr>
-<tr class="a">
+<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>573</td></tr>
-<tr class="b">
+<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.</t

<TRUNCATED>

[14/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span

<TRUNCATED>

[15/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode != null ? o

<TRUNCATED>

[26/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/checkstyle.rss
----------------------------------------------------------------------
diff --git a/checkstyle.rss b/checkstyle.rss
index b85063e..579f337 100644
--- a/checkstyle.rss
+++ b/checkstyle.rss
@@ -25,8 +25,8 @@ under the License.
     <language>en-us</language>
     <copyright>&#169;2007 - 2018 The Apache Software Foundation</copyright>
     <item>
-      <title>File: 3695,
-             Errors: 15633,
+      <title>File: 3696,
+             Errors: 15632,
              Warnings: 0,
              Infos: 0
       </title>
@@ -15894,6 +15894,20 @@ under the License.
               </tr>
                           <tr>
                 <td>
+                  <a href="http://hbase.apache.org/checkstyle.html#org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging.java">org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.java</a>
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
+              </tr>
+                          <tr>
+                <td>
                   <a href="http://hbase.apache.org/checkstyle.html#org.apache.hadoop.hbase.util.MapReduceExtendedCell.java">org/apache/hadoop/hbase/util/MapReduceExtendedCell.java</a>
                 </td>
                 <td>
@@ -37939,7 +37953,7 @@ under the License.
                   0
                 </td>
                 <td>
-                  1
+                  0
                 </td>
               </tr>
                           <tr>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/coc.html
----------------------------------------------------------------------
diff --git a/coc.html b/coc.html
index 2ec9736..c44ea99 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Code of Conduct Policy
@@ -375,7 +375,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/dependencies.html
----------------------------------------------------------------------
diff --git a/dependencies.html b/dependencies.html
index ec3bf5e..b8acd13 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Dependencies</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -440,7 +440,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/dependency-convergence.html
----------------------------------------------------------------------
diff --git a/dependency-convergence.html b/dependency-convergence.html
index 703bff8..6887e4d 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Reactor Dependency Convergence</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -905,7 +905,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/dependency-info.html
----------------------------------------------------------------------
diff --git a/dependency-info.html b/dependency-info.html
index f75e49e..860411e 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Dependency Information</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -313,7 +313,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/dependency-management.html
----------------------------------------------------------------------
diff --git a/dependency-management.html b/dependency-management.html
index dac58f5..cdc598a 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Dependency Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -1005,7 +1005,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/constant-values.html
----------------------------------------------------------------------
diff --git a/devapidocs/constant-values.html b/devapidocs/constant-values.html
index 37ebee4..48994b7 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -3789,21 +3789,21 @@
 <!--   -->
 </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 Jul 26 14:39:43 UTC 2018"</code></td>
+<td class="colLast"><code>"Fri Jul 27 14:40:32 UTC 2018"</code></td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.revision">
 <!--   -->
 </a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td><code><a href="org/apache/hadoop/hbase/Version.html#revision">revision</a></code></td>
-<td class="colLast"><code>"a392c017ed05c541403307e7fc75fbad38acff4a"</code></td>
+<td class="colLast"><code>"7178a98258dbb28496c2c4f3fbbf8e552ead8bdb"</code></td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.srcChecksum">
 <!--   -->
 </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>"9d54db4d371ad5e7218c7c216677d202"</code></td>
+<td class="colLast"><code>"a923cfae6952ac8068c6f7b0905a56a7"</code></td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.Version.url">
@@ -16710,6 +16710,25 @@
 </li>
 <li class="blockList">
 <table class="constantsSummary" border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
+<caption><span>org.apache.hadoop.hbase.procedure2.<a href="org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a></span><span class="tabEnd">&nbsp;</span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th scope="col">Constant Field</th>
+<th class="colLast" scope="col">Value</th>
+</tr>
+<tbody>
+<tr class="altColor">
+<td class="colFirst"><a name="org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException.serialVersionUID">
+<!--   -->
+</a><code>private&nbsp;static&nbsp;final&nbsp;long</code></td>
+<td><code><a href="org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#serialVersionUID">serialVersionUID</a></code></td>
+<td class="colLast"><code>-8328419627678496269L</code></td>
+</tr>
+</tbody>
+</table>
+</li>
+<li class="blockList">
+<table class="constantsSummary" border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
 <caption><span>org.apache.hadoop.hbase.procedure2.<a href="org/apache/hadoop/hbase/procedure2/RemoteProcedureDispatcher.html" title="class in org.apache.hadoop.hbase.procedure2">RemoteProcedureDispatcher</a>&lt;<a href="org/apache/hadoop/hbase/procedure2/RemoteProcedureDispatcher.html" title="type parameter in RemoteProcedureDispatcher">TEnv</a>,<a href="org/apache/hadoop/hbase/procedure2/RemoteProcedureDispatcher.html" title="type parameter in RemoteProcedureDispatcher">TRemote</a> extends <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/procedure2/RemoteProcedureDispatcher.html" title="type parameter in RemoteProcedureDispatcher">TRemote</a>&gt;&gt;</span><span class="tabEnd">&nbsp;</span></caption>
 <tr>
 <th class="colFirst" scope="col">Modifier and Type</th>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/index-all.html
----------------------------------------------------------------------
diff --git a/devapidocs/index-all.html b/devapidocs/index-all.html
index 0a6d673..223ef95 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -85891,6 +85891,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.ProcedureFuture.html#procExec">procExec</a></span> - Variable in class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.ProcedureFuture.html" title="class in org.apache.hadoop.hbase.master.procedure">ProcedureSyncWait.ProcedureFuture</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#procExecutionLock">procExecutionLock</a></span> - Variable in class org.apache.hadoop.hbase.procedure2.<a href="org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/HBaseAdmin.ProcedureFuture.html#procId">procId</a></span> - Variable in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/HBaseAdmin.ProcedureFuture.html" title="class in org.apache.hadoop.hbase.client">HBaseAdmin.ProcedureFuture</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/client/locking/EntityLock.html#procId">procId</a></span> - Variable in class org.apache.hadoop.hbase.client.locking.<a href="org/apache/hadoop/hbase/client/locking/EntityLock.html" title="class in org.apache.hadoop.hbase.client.locking">EntityLock</a></dt>
@@ -99313,6 +99315,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/NotServingRegionException.html#serialVersionUID">serialVersionUID</a></span> - Static variable in exception org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/NotServingRegionException.html" title="class in org.apache.hadoop.hbase">NotServingRegionException</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#serialVersionUID">serialVersionUID</a></span> - Static variable in exception org.apache.hadoop.hbase.procedure2.<a href="org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/quotas/FileArchiverNotifierImpl.QuotaSnapshotSizeSerializationException.html#serialVersionUID">serialVersionUID</a></span> - Static variable in exception org.apache.hadoop.hbase.quotas.<a href="org/apache/hadoop/hbase/quotas/FileArchiverNotifierImpl.QuotaSnapshotSizeSerializationException.html" title="class in org.apache.hadoop.hbase.quotas">FileArchiverNotifierImpl.QuotaSnapshotSizeSerializationException</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/quotas/SpaceLimitingException.html#serialVersionUID">serialVersionUID</a></span> - Static variable in exception org.apache.hadoop.hbase.quotas.<a href="org/apache/hadoop/hbase/quotas/SpaceLimitingException.html" title="class in org.apache.hadoop.hbase.quotas">SpaceLimitingException</a></dt>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html b/devapidocs/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html
index 857cb65..dd80dbd 100644
--- a/devapidocs/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html
+++ b/devapidocs/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html
@@ -272,7 +272,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>values</h4>
-<pre>public static&nbsp;<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase">HealthChecker.HealthCheckerExitStatus</a>[]&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html#line.39">values</a>()</pre>
+<pre>public static&nbsp;<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase">HealthChecker.HealthCheckerExitStatus</a>[]&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html#line.127">values</a>()</pre>
 <div class="block">Returns an array containing the constants of this enum type, in
 the order they are declared.  This method may be used to iterate
 over the constants as follows:
@@ -292,7 +292,7 @@ for (HealthChecker.HealthCheckerExitStatus c : HealthChecker.HealthCheckerExitSt
 <ul class="blockListLast">
 <li class="blockList">
 <h4>valueOf</h4>
-<pre>public static&nbsp;<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase">HealthChecker.HealthCheckerExitStatus</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html#line.39">valueOf</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;name)</pre>
+<pre>public static&nbsp;<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase">HealthChecker.HealthCheckerExitStatus</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html#line.127">valueOf</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;name)</pre>
 <div class="block">Returns the enum constant of this type with the specified name.
 The string must match <i>exactly</i> an identifier used to declare an
 enum constant in this type.  (Extraneous whitespace characters are 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 1e43e89..a2ca0d5 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.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/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/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.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 1f2b607..4f0b532 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
@@ -552,24 +552,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/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/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/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/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/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/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 8e9540a..ff495b5 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/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/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/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/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/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/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/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.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/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
+<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>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 97e13d7..faa09c1 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -273,12 +273,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" 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/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/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/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/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.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/Cacheable.MemoryType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">Cacheable.MemoryType</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/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 730b7cf..81c504b 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/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/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/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/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/SyncTable.SyncMapper.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">SyncTable.SyncMapper.Counter</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
index f0b1205..f5e8bd0 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static final class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1020">RegionStates.RegionFailedOpen</a>
+<pre>public static final class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1026">RegionStates.RegionFailedOpen</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>
@@ -229,7 +229,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionNode</h4>
-<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1021">regionNode</a></pre>
+<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1027">regionNode</a></pre>
 </li>
 </ul>
 <a name="exception">
@@ -238,7 +238,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>exception</h4>
-<pre>private volatile&nbsp;<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> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1023">exception</a></pre>
+<pre>private volatile&nbsp;<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> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1029">exception</a></pre>
 </li>
 </ul>
 <a name="retries">
@@ -247,7 +247,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>retries</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1024">retries</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1030">retries</a></pre>
 </li>
 </ul>
 </li>
@@ -264,7 +264,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1026">RegionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1032">RegionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
 </li>
@@ -281,7 +281,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionStateNode</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1030">getRegionStateNode</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1036">getRegionStateNode</a>()</pre>
 </li>
 </ul>
 <a name="getRegionInfo--">
@@ -290,7 +290,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionInfo</h4>
-<pre>public&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/master/assignment/RegionStates.RegionFailedOpen.html#line.1034">getRegionInfo</a>()</pre>
+<pre>public&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/master/assignment/RegionStates.RegionFailedOpen.html#line.1040">getRegionInfo</a>()</pre>
 </li>
 </ul>
 <a name="incrementAndGetRetries--">
@@ -299,7 +299,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>incrementAndGetRetries</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1038">incrementAndGetRetries</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1044">incrementAndGetRetries</a>()</pre>
 </li>
 </ul>
 <a name="getRetries--">
@@ -308,7 +308,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRetries</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1042">getRetries</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1048">getRetries</a>()</pre>
 </li>
 </ul>
 <a name="setException-java.lang.Exception-">
@@ -317,7 +317,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setException</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1046">setException</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;exception)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1052">setException</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;exception)</pre>
 </li>
 </ul>
 <a name="getException--">
@@ -326,7 +326,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getException</h4>
-<pre>public&nbsp;<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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1050">getException</a>()</pre>
+<pre>public&nbsp;<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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.1056">getException</a>()</pre>
 </li>
 </ul>
 </li>


[11/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isF

<TRUNCATED>

[05/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line.482"></a>
-<span class="sourceLineNo">483</s

<TRUNCATED>

[24/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
index 8984144..e293605 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.111">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;TEnvironment&gt;
+<pre>private static final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.112">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;TEnvironment&gt;
 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>
@@ -223,7 +223,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>procedure</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.112">procedure</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.113">procedure</a></pre>
 </li>
 </ul>
 <a name="clientAckTime">
@@ -232,7 +232,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>clientAckTime</h4>
-<pre>private&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.113">clientAckTime</a></pre>
+<pre>private&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.114">clientAckTime</a></pre>
 </li>
 </ul>
 </li>
@@ -249,7 +249,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CompletedProcedureRetainer</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.115">CompletedProcedureRetainer</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt;&nbsp;procedure)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.116">CompletedProcedureRetainer</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt;&nbsp;procedure)</pre>
 </li>
 </ul>
 </li>
@@ -266,7 +266,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.120">getProcedure</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="type parameter in ProcedureExecutor.CompletedProcedureRetainer">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.121">getProcedure</a>()</pre>
 </li>
 </ul>
 <a name="hasClientAckTime--">
@@ -275,7 +275,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasClientAckTime</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.124">hasClientAckTime</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.125">hasClientAckTime</a>()</pre>
 </li>
 </ul>
 <a name="getClientAckTime--">
@@ -284,7 +284,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getClientAckTime</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.128">getClientAckTime</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.129">getClientAckTime</a>()</pre>
 </li>
 </ul>
 <a name="setClientAckTime-long-">
@@ -293,7 +293,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setClientAckTime</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.132">setClientAckTime</a>(long&nbsp;clientAckTime)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.133">setClientAckTime</a>(long&nbsp;clientAckTime)</pre>
 </li>
 </ul>
 <a name="isExpired-long-long-long-">
@@ -302,7 +302,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>isExpired</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.136">isExpired</a>(long&nbsp;now,
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html#line.137">isExpired</a>(long&nbsp;now,
                          long&nbsp;evictTtl,
                          long&nbsp;evictAckTtl)</pre>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
index 8d0ad86..c8238a4 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.820">ProcedureExecutor.FailedProcedure</a>&lt;TEnvironment&gt;
+<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.829">ProcedureExecutor.FailedProcedure</a>&lt;TEnvironment&gt;
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;TEnvironment&gt;</pre>
 </li>
 </ul>
@@ -279,7 +279,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockListLast">
 <li class="blockList">
 <h4>procName</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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.821">procName</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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.830">procName</a></pre>
 </li>
 </ul>
 </li>
@@ -296,7 +296,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>FailedProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.823">FailedProcedure</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.832">FailedProcedure</a>()</pre>
 </li>
 </ul>
 <a name="FailedProcedure-long-java.lang.String-org.apache.hadoop.hbase.security.User-org.apache.hadoop.hbase.util.NonceKey-java.io.IOException-">
@@ -305,7 +305,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FailedProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.826">FailedProcedure</a>(long&nbsp;procId,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.835">FailedProcedure</a>(long&nbsp;procId,
                        <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;procName,
                        <a href="../../../../../org/apache/hadoop/hbase/security/User.html" title="class in org.apache.hadoop.hbase.security">User</a>&nbsp;owner,
                        <a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey,
@@ -326,7 +326,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcName</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/procedure2/ProcedureExecutor.FailedProcedure.html#line.840">getProcName</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/procedure2/ProcedureExecutor.FailedProcedure.html#line.849">getProcName</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#getProcName--">getProcName</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&gt;</code></dd>
@@ -341,7 +341,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>execute</h4>
-<pre>protected&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&gt;[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.845">execute</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)
+<pre>protected&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&gt;[]&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.854">execute</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)
                                      throws <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureYieldException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureYieldException</a>,
                                             <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a>,
                                             <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
@@ -373,7 +373,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>rollback</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.852">rollback</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.861">rollback</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)
                  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="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#rollback-TEnvironment-">Procedure</a></code></span></div>
@@ -402,7 +402,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>abort</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.858">abort</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.867">abort</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html" title="type parameter in ProcedureExecutor.FailedProcedure">TEnvironment</a>&nbsp;env)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#abort-TEnvironment-">Procedure</a></code></span></div>
 <div class="block">The abort() call is asynchronous and each procedure must decide how to deal
  with it, if they want to be abortable. The simplest implementation
@@ -425,7 +425,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockList">
 <li class="blockList">
 <h4>serializeStateData</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.863">serializeStateData</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.872">serializeStateData</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
                            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/procedure2/Procedure.html#serializeStateData-org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer-">Procedure</a></code></span></div>
 <div class="block">The user-level code of the procedure may have some state to
@@ -447,7 +447,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.htm
 <ul class="blockListLast">
 <li class="blockList">
 <h4>deserializeStateData</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.868">deserializeStateData</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.FailedProcedure.html#line.877">deserializeStateData</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
                              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/procedure2/Procedure.html#deserializeStateData-org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer-">Procedure</a></code></span></div>
 <div class="block">Called on store load to allow the user to decode the previously serialized

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
index 3d98775..b02032d 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
@@ -132,7 +132,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1845">ProcedureExecutor.KeepAliveWorkerThread</a>
+<pre>private final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1849">ProcedureExecutor.KeepAliveWorkerThread</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.WorkerThread</a></pre>
 </li>
 </ul>
@@ -252,7 +252,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExec
 <ul class="blockListLast">
 <li class="blockList">
 <h4>KeepAliveWorkerThread</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html#line.1847">KeepAliveWorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html#line.1851">KeepAliveWorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group)</pre>
 </li>
 </ul>
 </li>
@@ -269,7 +269,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExec
 <ul class="blockListLast">
 <li class="blockList">
 <h4>keepAlive</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html#line.1852">keepAlive</a>(long&nbsp;lastUpdate)</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html#line.1856">keepAlive</a>(long&nbsp;lastUpdate)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#keepAlive-long-">keepAlive</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.WorkerThread</a></code></dd>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
index 6c92515..b136d34 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
@@ -105,7 +105,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static interface <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.105">ProcedureExecutor.ProcedureExecutorListener</a></pre>
+<pre>public static interface <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.106">ProcedureExecutor.ProcedureExecutorListener</a></pre>
 </li>
 </ul>
 </div>
@@ -157,7 +157,7 @@ var activeTableTab = "activeTableTab";
 <ul class="blockList">
 <li class="blockList">
 <h4>procedureLoaded</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.106">procedureLoaded</a>(long&nbsp;procId)</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.107">procedureLoaded</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="procedureAdded-long-">
@@ -166,7 +166,7 @@ var activeTableTab = "activeTableTab";
 <ul class="blockList">
 <li class="blockList">
 <h4>procedureAdded</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.107">procedureAdded</a>(long&nbsp;procId)</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.108">procedureAdded</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="procedureFinished-long-">
@@ -175,7 +175,7 @@ var activeTableTab = "activeTableTab";
 <ul class="blockListLast">
 <li class="blockList">
 <h4>procedureFinished</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.108">procedureFinished</a>(long&nbsp;procId)</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html#line.109">procedureFinished</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
index 11b5890..a0d9b1a 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.86">ProcedureExecutor.Testing</a>
+<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.87">ProcedureExecutor.Testing</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>
@@ -213,7 +213,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>killIfSuspended</h4>
-<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.87">killIfSuspended</a></pre>
+<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.88">killIfSuspended</a></pre>
 </li>
 </ul>
 <a name="killBeforeStoreUpdate">
@@ -222,7 +222,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>killBeforeStoreUpdate</h4>
-<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.88">killBeforeStoreUpdate</a></pre>
+<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.89">killBeforeStoreUpdate</a></pre>
 </li>
 </ul>
 <a name="toggleKillBeforeStoreUpdate">
@@ -231,7 +231,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>toggleKillBeforeStoreUpdate</h4>
-<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.89">toggleKillBeforeStoreUpdate</a></pre>
+<pre>protected&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.90">toggleKillBeforeStoreUpdate</a></pre>
 </li>
 </ul>
 </li>
@@ -248,7 +248,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>Testing</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.86">Testing</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.87">Testing</a>()</pre>
 </li>
 </ul>
 </li>
@@ -265,7 +265,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>shouldKillBeforeStoreUpdate</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.91">shouldKillBeforeStoreUpdate</a>()</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.92">shouldKillBeforeStoreUpdate</a>()</pre>
 </li>
 </ul>
 <a name="shouldKillBeforeStoreUpdate-boolean-">
@@ -274,7 +274,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>shouldKillBeforeStoreUpdate</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.100">shouldKillBeforeStoreUpdate</a>(boolean&nbsp;isSuspended)</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html#line.101">shouldKillBeforeStoreUpdate</a>(boolean&nbsp;isSuspended)</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
index 0f643f0..3c04230 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
@@ -127,7 +127,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1865">ProcedureExecutor.WorkerMonitor</a>
+<pre>private final class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1869">ProcedureExecutor.WorkerMonitor</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.html" title="class in org.apache.hadoop.hbase.procedure2">InlineChore</a></pre>
 </li>
 </ul>
@@ -277,7 +277,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>WORKER_MONITOR_INTERVAL_CONF_KEY</h4>
-<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1866">WORKER_MONITOR_INTERVAL_CONF_KEY</a></pre>
+<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1870">WORKER_MONITOR_INTERVAL_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.WORKER_MONITOR_INTERVAL_CONF_KEY">Constant Field Values</a></dd>
@@ -290,7 +290,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_WORKER_MONITOR_INTERVAL</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1868">DEFAULT_WORKER_MONITOR_INTERVAL</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1872">DEFAULT_WORKER_MONITOR_INTERVAL</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.DEFAULT_WORKER_MONITOR_INTERVAL">Constant Field Values</a></dd>
@@ -303,7 +303,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>WORKER_STUCK_THRESHOLD_CONF_KEY</h4>
-<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1870">WORKER_STUCK_THRESHOLD_CONF_KEY</a></pre>
+<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1874">WORKER_STUCK_THRESHOLD_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.WORKER_STUCK_THRESHOLD_CONF_KEY">Constant Field Values</a></dd>
@@ -316,7 +316,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_WORKER_STUCK_THRESHOLD</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1872">DEFAULT_WORKER_STUCK_THRESHOLD</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1876">DEFAULT_WORKER_STUCK_THRESHOLD</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.DEFAULT_WORKER_STUCK_THRESHOLD">Constant Field Values</a></dd>
@@ -329,7 +329,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>WORKER_ADD_STUCK_PERCENTAGE_CONF_KEY</h4>
-<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1874">WORKER_ADD_STUCK_PERCENTAGE_CONF_KEY</a></pre>
+<pre>public 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/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1878">WORKER_ADD_STUCK_PERCENTAGE_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.WORKER_ADD_STUCK_PERCENTAGE_CONF_KEY">Constant Field Values</a></dd>
@@ -342,7 +342,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_WORKER_ADD_STUCK_PERCENTAGE</h4>
-<pre>private static final&nbsp;float <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1876">DEFAULT_WORKER_ADD_STUCK_PERCENTAGE</a></pre>
+<pre>private static final&nbsp;float <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1880">DEFAULT_WORKER_ADD_STUCK_PERCENTAGE</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WorkerMonitor.DEFAULT_WORKER_ADD_STUCK_PERCENTAGE">Constant Field Values</a></dd>
@@ -355,7 +355,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>addWorkerStuckPercentage</h4>
-<pre>private&nbsp;float <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1878">addWorkerStuckPercentage</a></pre>
+<pre>private&nbsp;float <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1882">addWorkerStuckPercentage</a></pre>
 </li>
 </ul>
 <a name="timeoutInterval">
@@ -364,7 +364,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>timeoutInterval</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1879">timeoutInterval</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1883">timeoutInterval</a></pre>
 </li>
 </ul>
 <a name="stuckThreshold">
@@ -373,7 +373,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockListLast">
 <li class="blockList">
 <h4>stuckThreshold</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1880">stuckThreshold</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1884">stuckThreshold</a></pre>
 </li>
 </ul>
 </li>
@@ -390,7 +390,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockListLast">
 <li class="blockList">
 <h4>WorkerMonitor</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1882">WorkerMonitor</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1886">WorkerMonitor</a>()</pre>
 </li>
 </ul>
 </li>
@@ -407,7 +407,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>run</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1887">run</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1891">run</a>()</pre>
 </li>
 </ul>
 <a name="checkForStuckWorkers--">
@@ -416,7 +416,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>checkForStuckWorkers</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1895">checkForStuckWorkers</a>()</pre>
+<pre>private&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1899">checkForStuckWorkers</a>()</pre>
 </li>
 </ul>
 <a name="checkThreadCount-int-">
@@ -425,7 +425,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>checkThreadCount</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1911">checkThreadCount</a>(int&nbsp;stuckCount)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1915">checkThreadCount</a>(int&nbsp;stuckCount)</pre>
 </li>
 </ul>
 <a name="refreshConfig--">
@@ -434,7 +434,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockList">
 <li class="blockList">
 <h4>refreshConfig</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1930">refreshConfig</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1934">refreshConfig</a>()</pre>
 </li>
 </ul>
 <a name="getTimeoutInterval--">
@@ -443,7 +443,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.h
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getTimeoutInterval</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1940">getTimeoutInterval</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html#line.1944">getTimeoutInterval</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.html#getTimeoutInterval--">getTimeoutInterval</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/InlineChore.html" title="class in org.apache.hadoop.hbase.procedure2">InlineChore</a></code></dd>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
index 0848ee2..e3af5a0 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html
@@ -131,7 +131,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1768">ProcedureExecutor.WorkerThread</a>
+<pre>private class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1770">ProcedureExecutor.WorkerThread</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThread.html" title="class in org.apache.hadoop.hbase.procedure2">StoppableThread</a></pre>
 </li>
 </ul>
@@ -282,7 +282,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockList">
 <li class="blockList">
 <h4>executionStartTime</h4>
-<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1769">executionStartTime</a></pre>
+<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1771">executionStartTime</a></pre>
 </li>
 </ul>
 <a name="activeProcedure">
@@ -291,7 +291,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockListLast">
 <li class="blockList">
 <h4>activeProcedure</h4>
-<pre>private volatile&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1770">activeProcedure</a></pre>
+<pre>private volatile&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1772">activeProcedure</a></pre>
 </li>
 </ul>
 </li>
@@ -308,7 +308,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockList">
 <li class="blockList">
 <h4>WorkerThread</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1772">WorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1774">WorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group)</pre>
 </li>
 </ul>
 <a name="WorkerThread-java.lang.ThreadGroup-java.lang.String-">
@@ -317,7 +317,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockListLast">
 <li class="blockList">
 <h4>WorkerThread</h4>
-<pre>protected&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1776">WorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group,
+<pre>protected&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1778">WorkerThread</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a>&nbsp;group,
                        <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;prefix)</pre>
 </li>
 </ul>
@@ -335,7 +335,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockList">
 <li class="blockList">
 <h4>sendStopSignal</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1782">sendStopSignal</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1784">sendStopSignal</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThread.html#sendStopSignal--">sendStopSignal</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThread.html" title="class in org.apache.hadoop.hbase.procedure2">StoppableThread</a></code></dd>
@@ -348,7 +348,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockList">
 <li class="blockList">
 <h4>run</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1787">run</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1789">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>
@@ -363,7 +363,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <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/procedure2/ProcedureExecutor.WorkerThread.html#line.1825">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/procedure2/ProcedureExecutor.WorkerThread.html#line.1829">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/Thread.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/Thread.html?is-external=true" title="class or interface in java.lang">Thread</a></code></dd>
@@ -376,7 +376,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockList">
 <li class="blockList">
 <h4>getCurrentRunTime</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1833">getCurrentRunTime</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1837">getCurrentRunTime</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the time since the current procedure is running</dd>
@@ -389,7 +389,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/StoppableThre
 <ul class="blockListLast">
 <li class="blockList">
 <h4>keepAlive</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1838">keepAlive</a>(long&nbsp;lastUpdate)</pre>
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html#line.1842">keepAlive</a>(long&nbsp;lastUpdate)</pre>
 </li>
 </ul>
 </li>


[02/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/allclasses-frame.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/allclasses-frame.html b/testdevapidocs/allclasses-frame.html
index 53ed3e1..452a48f 100644
--- a/testdevapidocs/allclasses-frame.html
+++ b/testdevapidocs/allclasses-frame.html
@@ -1513,6 +1513,7 @@
 <li><a href="org/apache/hadoop/hbase/rest/model/TestModelBase.html" title="class in org.apache.hadoop.hbase.rest.model" target="classFrame">TestModelBase</a></li>
 <li><a href="org/apache/hadoop/hbase/master/procedure/TestModifyNamespaceProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure" target="classFrame">TestModifyNamespaceProcedure</a></li>
 <li><a href="org/apache/hadoop/hbase/master/procedure/TestModifyTableProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure" target="classFrame">TestModifyTableProcedure</a></li>
+<li><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestModifyTableWhileMerging</a></li>
 <li><a href="org/apache/hadoop/hbase/TestMovedRegionsCleaner.html" title="class in org.apache.hadoop.hbase" target="classFrame">TestMovedRegionsCleaner</a></li>
 <li><a href="org/apache/hadoop/hbase/TestMovedRegionsCleaner.TestMockRegionServer.html" title="class in org.apache.hadoop.hbase" target="classFrame">TestMovedRegionsCleaner.TestMockRegionServer</a></li>
 <li><a href="org/apache/hadoop/hbase/nio/TestMultiByteBuff.html" title="class in org.apache.hadoop.hbase.nio" target="classFrame">TestMultiByteBuff</a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/allclasses-noframe.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/allclasses-noframe.html b/testdevapidocs/allclasses-noframe.html
index 9c93c99..9fd26d1 100644
--- a/testdevapidocs/allclasses-noframe.html
+++ b/testdevapidocs/allclasses-noframe.html
@@ -1513,6 +1513,7 @@
 <li><a href="org/apache/hadoop/hbase/rest/model/TestModelBase.html" title="class in org.apache.hadoop.hbase.rest.model">TestModelBase</a></li>
 <li><a href="org/apache/hadoop/hbase/master/procedure/TestModifyNamespaceProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">TestModifyNamespaceProcedure</a></li>
 <li><a href="org/apache/hadoop/hbase/master/procedure/TestModifyTableProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">TestModifyTableProcedure</a></li>
+<li><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></li>
 <li><a href="org/apache/hadoop/hbase/TestMovedRegionsCleaner.html" title="class in org.apache.hadoop.hbase">TestMovedRegionsCleaner</a></li>
 <li><a href="org/apache/hadoop/hbase/TestMovedRegionsCleaner.TestMockRegionServer.html" title="class in org.apache.hadoop.hbase">TestMovedRegionsCleaner.TestMockRegionServer</a></li>
 <li><a href="org/apache/hadoop/hbase/nio/TestMultiByteBuff.html" title="class in org.apache.hadoop.hbase.nio">TestMultiByteBuff</a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/index-all.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/index-all.html b/testdevapidocs/index-all.html
index bdb56ad..f294719 100644
--- a/testdevapidocs/index-all.html
+++ b/testdevapidocs/index-all.html
@@ -909,6 +909,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#admin">admin</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#admin">admin</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#admin">admin</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRogueRSAssignment</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.html#admin">admin</a></span> - Variable in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/TestFavoredStochasticBalancerPickers.html" title="class in org.apache.hadoop.hbase.master.balancer">TestFavoredStochasticBalancerPickers</a></dt>
@@ -3331,6 +3333,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#CF">CF</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMasterAbortWhileMergingTable</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#CF">CF</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.html#CF">CF</a></span> - Variable in class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">TestCloneSnapshotProcedure</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/TestProcedurePriority.html#CF">CF</a></span> - Static variable in class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/TestProcedurePriority.html" title="class in org.apache.hadoop.hbase.master.procedure">TestProcedurePriority</a></dt>
@@ -4975,6 +4979,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#CLASS_RULE">CLASS_RULE</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#CLASS_RULE">CLASS_RULE</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#CLASS_RULE">CLASS_RULE</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionMoveAndAbandon</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#CLASS_RULE">CLASS_RULE</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionStates</a></dt>
@@ -6713,6 +6719,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#cleanupTest--">cleanupTest()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#cleanupTest--">cleanupTest()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#cleanupTest--">cleanupTest()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRogueRSAssignment</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#cleanupTest--">cleanupTest()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestSplitTableRegionProcedure</a></dt>
@@ -6799,6 +6807,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/coprocessor/TestPassCustomCellViaRegionObserver.html#clearTable--">clearTable()</a></span> - Method in class org.apache.hadoop.hbase.coprocessor.<a href="org/apache/hadoop/hbase/coprocessor/TestPassCustomCellViaRegionObserver.html" title="class in org.apache.hadoop.hbase.coprocessor">TestPassCustomCellViaRegionObserver</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#client">client</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/TestHdfsSnapshotHRegion.html#client">client</a></span> - Variable in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestHdfsSnapshotHRegion.html" title="class in org.apache.hadoop.hbase.regionserver">TestHdfsSnapshotHRegion</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.html#client">client</a></span> - Variable in class org.apache.hadoop.hbase.rest.client.<a href="org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.html" title="class in org.apache.hadoop.hbase.rest.client">TestRemoteAdminRetries</a></dt>
@@ -23412,6 +23422,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#LOG">LOG</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#LOG">LOG</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#LOG">LOG</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionMoveAndAbandon</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#LOG">LOG</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionStates</a></dt>
@@ -37836,6 +37848,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#setupCluster--">setupCluster()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#setupCluster--">setupCluster()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#setupCluster--">setupCluster()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRogueRSAssignment</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#setupCluster--">setupCluster()</a></span> - Static method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestSplitTableRegionProcedure</a></dt>
@@ -39072,6 +39086,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#SPLITKEY">SPLITKEY</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMasterAbortWhileMergingTable</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#SPLITKEY">SPLITKEY</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/TestMergeTableRegionsWhileRSCrash.html#SPLITKEY">SPLITKEY</a></span> - Static variable in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestMergeTableRegionsWhileRSCrash.html" title="class in org.apache.hadoop.hbase.master">TestMergeTableRegionsWhileRSCrash</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/TestHStoreFile.html#SPLITKEY">SPLITKEY</a></span> - Variable in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestHStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">TestHStoreFile</a></dt>
@@ -40868,6 +40884,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#TABLE_NAME">TABLE_NAME</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMasterAbortWhileMergingTable</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#TABLE_NAME">TABLE_NAME</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/cleaner/TestSnapshotFromMaster.html#TABLE_NAME">TABLE_NAME</a></span> - Static variable in class org.apache.hadoop.hbase.master.cleaner.<a href="org/apache/hadoop/hbase/master/cleaner/TestSnapshotFromMaster.html" title="class in org.apache.hadoop.hbase.master.cleaner">TestSnapshotFromMaster</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.html#TABLE_NAME">TABLE_NAME</a></span> - Static variable in class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/TestTableDescriptorModificationFromClient.html" title="class in org.apache.hadoop.hbase.master.procedure">TestTableDescriptorModificationFromClient</a></dt>
@@ -42696,6 +42714,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#test--">test()</a></span> - Method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMasterAbortWhileMergingTable</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#test--">test()</a></span> - Method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#test--">test()</a></span> - Method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionMoveAndAbandon</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/balancer/TestServerAndLoad.html#test--">test()</a></span> - Method in class org.apache.hadoop.hbase.master.balancer.<a href="org/apache/hadoop/hbase/master/balancer/TestServerAndLoad.html" title="class in org.apache.hadoop.hbase.master.balancer">TestServerAndLoad</a></dt>
@@ -46468,6 +46488,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/TestStripeStoreFileManager.html#testClearFiles--">testClearFiles()</a></span> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestStripeStoreFileManager.html" title="class in org.apache.hadoop.hbase.regionserver">TestStripeStoreFileManager</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html#testClearNotProcessedDeadServer--">testClearNotProcessedDeadServer()</a></span> - Method in class org.apache.hadoop.hbase.rsgroup.<a href="org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.html" title="class in org.apache.hadoop.hbase.rsgroup">TestRSGroupsBase</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/regionserver/TestClearRegionBlockCache.html" title="class in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestClearRegionBlockCache</span></a> - Class in <a href="org/apache/hadoop/hbase/regionserver/package-summary.html">org.apache.hadoop.hbase.regionserver</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/regionserver/TestClearRegionBlockCache.html#TestClearRegionBlockCache--">TestClearRegionBlockCache()</a></span> - Constructor for class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestClearRegionBlockCache.html" title="class in org.apache.hadoop.hbase.regionserver">TestClearRegionBlockCache</a></dt>
@@ -54605,6 +54627,10 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/TestModifyTableProcedure.html#TestModifyTableProcedure--">TestModifyTableProcedure()</a></span> - Constructor for class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/TestModifyTableProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">TestModifyTableProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestModifyTableWhileMerging</span></a> - Class in <a href="org/apache/hadoop/hbase/master/assignment/package-summary.html">org.apache.hadoop.hbase.master.assignment</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#TestModifyTableWhileMerging--">TestModifyTableWhileMerging()</a></span> - Constructor for class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/TestIntegrationTestBase.html#testMonkeyPropertiesParsing--">testMonkeyPropertiesParsing()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/TestIntegrationTestBase.html" title="class in org.apache.hadoop.hbase">TestIntegrationTestBase</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/TestKeyValue.html#testMoreComparisons--">testMoreComparisons()</a></span> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/TestKeyValue.html" title="class in org.apache.hadoop.hbase">TestKeyValue</a></dt>
@@ -66105,6 +66131,8 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#UTIL">UTIL</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestMergeTableRegionsProcedure</a></dt>
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#UTIL">UTIL</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#UTIL">UTIL</a></span> - Variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionMoveAndAbandon</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#UTIL">UTIL</a></span> - Static variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionStates</a></dt>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/backup/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/backup/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/backup/package-tree.html
index 6af42fe..2d9b60f 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/backup/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/backup/package-tree.html
@@ -146,8 +146,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.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/TestIncrementalBackupMergeWithFailures.FailurePhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">TestIncrementalBackupMergeWithFailures.FailurePhase</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/TestBackupDeleteWithFailures.Failure.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">TestBackupDeleteWithFailures.Failure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/TestIncrementalBackupMergeWithFailures.FailurePhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">TestIncrementalBackupMergeWithFailures.FailurePhase</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseClassTestRule.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseClassTestRule.html b/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseClassTestRule.html
index a07af65..763d3d9 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseClassTestRule.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseClassTestRule.html
@@ -3323,38 +3323,42 @@
 <tbody>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestUnexpectedStateException.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestUnexpectedStateException.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestModifyTableWhileMerging.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestMasterAbortWhileMergingTable.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestUnexpectedStateException.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestUnexpectedStateException.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestSplitTableRegionProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestMasterAbortWhileMergingTable.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestRegionStates.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestSplitTableRegionProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestRegionMoveAndAbandon.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestRegionStates.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestRogueRSAssignment.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestRegionMoveAndAbandon.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestAssignmentOnRSCrash.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestAssignmentOnRSCrash.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestRogueRSAssignment.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestMergeTableRegionsProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestAssignmentOnRSCrash.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestAssignmentOnRSCrash.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
+<td class="colLast"><span class="typeNameLabel">TestMergeTableRegionsProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestAssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestAssignmentManager.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
 </tr>
 </tbody>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseTestingUtility.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseTestingUtility.html b/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseTestingUtility.html
index 239fb1e..38cc11c 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseTestingUtility.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/class-use/HBaseTestingUtility.html
@@ -2132,33 +2132,37 @@
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>protected static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestMasterAbortWhileMergingTable.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#UTIL">UTIL</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestModifyTableWhileMerging.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
 <td class="colFirst"><code>protected static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestSplitTableRegionProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#UTIL">UTIL</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestMasterAbortWhileMergingTable.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
 <tr class="rowColor">
 <td class="colFirst"><code>protected static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
-<td class="colLast"><span class="typeNameLabel">TestRegionStates.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#UTIL">UTIL</a></span></code>&nbsp;</td>
+<td class="colLast"><span class="typeNameLabel">TestSplitTableRegionProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
 <tr class="altColor">
+<td class="colFirst"><code>protected static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
+<td class="colLast"><span class="typeNameLabel">TestRegionStates.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html#UTIL">UTIL</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestRegionMoveAndAbandon.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestRogueRSAssignment.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestAssignmentOnRSCrash.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestAssignmentOnRSCrash.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>protected static <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestMergeTableRegionsProcedure.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TestAssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/master/assignment/TestAssignmentManager.html#UTIL">UTIL</a></span></code>&nbsp;</td>
 </tr>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html
index c7ddd8d..e91960b 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html
@@ -50,7 +50,7 @@ var activeTableTab = "activeTableTab";
 <div class="subNav">
 <ul class="navList">
 <li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.MergeRegionObserver.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
-<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
 </ul>
 <ul class="navList">
 <li><a href="../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" target="_top">Frames</a></li>
@@ -759,7 +759,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <div class="subNav">
 <ul class="navList">
 <li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.MergeRegionObserver.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
-<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
 </ul>
 <ul class="navList">
 <li><a href="../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" target="_top">Frames</a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
new file mode 100644
index 0000000..37667c0
--- /dev/null
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html
@@ -0,0 +1,440 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc -->
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>TestModifyTableWhileMerging (Apache HBase 3.0.0-SNAPSHOT Test API)</title>
+<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
+<script type="text/javascript" src="../../../../../../script.js"></script>
+</head>
+<body>
+<script type="text/javascript"><!--
+    try {
+        if (location.href.indexOf('is-external=true') == -1) {
+            parent.document.title="TestModifyTableWhileMerging (Apache HBase 3.0.0-SNAPSHOT Test API)";
+        }
+    }
+    catch(err) {
+    }
+//-->
+var methods = {"i0":9,"i1":9,"i2":10};
+var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
+var altColor = "altColor";
+var rowColor = "rowColor";
+var tableTab = "tableTab";
+var activeTableTab = "activeTableTab";
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar.top">
+<!--   -->
+</a>
+<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
+<a name="navbar.top.firstrow">
+<!--   -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../../../../../../overview-summary.html">Overview</a></li>
+<li><a href="package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="class-use/TestModifyTableWhileMerging.html">Use</a></li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" target="_top">Frames</a></li>
+<li><a href="TestModifyTableWhileMerging.html" target="_top">No&nbsp;Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+  allClassesLink = document.getElementById("allclasses_navbar_top");
+  if(window==top) {
+    allClassesLink.style.display = "block";
+  }
+  else {
+    allClassesLink.style.display = "none";
+  }
+  //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary:&nbsp;</li>
+<li>Nested&nbsp;|&nbsp;</li>
+<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
+<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
+<li><a href="#method.summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail:&nbsp;</li>
+<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
+<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
+<li><a href="#method.detail">Method</a></li>
+</ul>
+</div>
+<a name="skip.navbar.top">
+<!--   -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">org.apache.hadoop.hbase.master.assignment</div>
+<h2 title="Class TestModifyTableWhileMerging" class="title">Class TestModifyTableWhileMerging</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">java.lang.Object</a></li>
+<li>
+<ul class="inheritance">
+<li>org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.49">TestModifyTableWhileMerging</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>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field.summary">
+<!--   -->
+</a>
+<h3>Field Summary</h3>
+<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>private static org.apache.hadoop.hbase.client.Admin</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#admin">admin</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>private static byte[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#CF">CF</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#CLASS_RULE">CLASS_RULE</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>private static org.apache.hadoop.hbase.client.Table</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#client">client</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>private static org.slf4j.Logger</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#LOG">LOG</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>private static byte[]</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#SPLITKEY">SPLITKEY</a></span></code>&nbsp;</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>private static org.apache.hadoop.hbase.TableName</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#TABLE_NAME">TABLE_NAME</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected static <a href="../../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#UTIL">UTIL</a></span></code>&nbsp;</td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor.summary">
+<!--   -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#TestModifyTableWhileMerging--">TestModifyTableWhileMerging</a></span>()</code>&nbsp;</td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method.summary">
+<!--   -->
+</a>
+<h3>Method Summary</h3>
+<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t1" class="tableTab"><span><a href="javascript:show(1);">Static Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr id="i0" class="altColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#cleanupTest--">cleanupTest</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i1" class="rowColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#setupCluster--">setupCluster</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i2" class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#test--">test</a></span>()</code>&nbsp;</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods.inherited.from.class.java.lang.Object">
+<!--   -->
+</a>
+<h3>Methods inherited from class&nbsp;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">Object</a></h3>
+<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#clone--" title="class or interface in java.lang">clone</a>, <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>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#finalize--" title="class or interface in java.lang">finalize</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#getClass--" title="class or interface in java.lang">getClass</a>, <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>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#notify--" title="class or interface in java.lang">notify</a>, <a href="https://docs.oracle.com/javase/8/docs/api/ja
 va/lang/Object.html?is-external=true#notifyAll--" title="class or interface in java.lang">notifyAll</a>, <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>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#wait--" title="class or interface in java.lang">wait</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#wait-long-" title="class or interface in java.lang">wait</a>, <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#wait-long-int-" title="class or interface in java.lang">wait</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field.detail">
+<!--   -->
+</a>
+<h3>Field Detail</h3>
+<a name="CLASS_RULE">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>CLASS_RULE</h4>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.52">CLASS_RULE</a></pre>
+</li>
+</ul>
+<a name="LOG">
+<!--   -->
+</a>
+<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/assignment/TestModifyTableWhileMerging.html#line.55">LOG</a></pre>
+</li>
+</ul>
+<a name="UTIL">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>UTIL</h4>
+<pre>protected static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/HBaseTestingUtility.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtility</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.58">UTIL</a></pre>
+</li>
+</ul>
+<a name="TABLE_NAME">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>TABLE_NAME</h4>
+<pre>private static&nbsp;org.apache.hadoop.hbase.TableName <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.59">TABLE_NAME</a></pre>
+</li>
+</ul>
+<a name="admin">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>admin</h4>
+<pre>private static&nbsp;org.apache.hadoop.hbase.client.Admin <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.60">admin</a></pre>
+</li>
+</ul>
+<a name="client">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>client</h4>
+<pre>private static&nbsp;org.apache.hadoop.hbase.client.Table <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.61">client</a></pre>
+</li>
+</ul>
+<a name="CF">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>CF</h4>
+<pre>private static&nbsp;byte[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.62">CF</a></pre>
+</li>
+</ul>
+<a name="SPLITKEY">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>SPLITKEY</h4>
+<pre>private static&nbsp;byte[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.63">SPLITKEY</a></pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor.detail">
+<!--   -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="TestModifyTableWhileMerging--">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>TestModifyTableWhileMerging</h4>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.49">TestModifyTableWhileMerging</a>()</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method.detail">
+<!--   -->
+</a>
+<h3>Method Detail</h3>
+<a name="setupCluster--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>setupCluster</h4>
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.66">setupCluster</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>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+<a name="cleanupTest--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>cleanupTest</h4>
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.78">cleanupTest</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>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+<a name="test--">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>test</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html#line.87">test</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>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar.bottom">
+<!--   -->
+</a>
+<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
+<a name="navbar.bottom.firstrow">
+<!--   -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../../../../../../overview-summary.html">Overview</a></li>
+<li><a href="package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="class-use/TestModifyTableWhileMerging.html">Use</a></li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" target="_top">Frames</a></li>
+<li><a href="TestModifyTableWhileMerging.html" target="_top">No&nbsp;Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+  allClassesLink = document.getElementById("allclasses_navbar_bottom");
+  if(window==top) {
+    allClassesLink.style.display = "block";
+  }
+  else {
+    allClassesLink.style.display = "none";
+  }
+  //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary:&nbsp;</li>
+<li>Nested&nbsp;|&nbsp;</li>
+<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
+<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
+<li><a href="#method.summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail:&nbsp;</li>
+<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
+<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
+<li><a href="#method.detail">Method</a></li>
+</ul>
+</div>
+<a name="skip.navbar.bottom">
+<!--   -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+<p class="legalCopy"><small>Copyright &#169; 2007&#x2013;2018 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html
index 478a10c..6a00d7b 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html
@@ -49,7 +49,7 @@ var activeTableTab = "activeTableTab";
 </div>
 <div class="subNav">
 <ul class="navList">
-<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
 <li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
 </ul>
 <ul class="navList">
@@ -408,7 +408,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </div>
 <div class="subNav">
 <ul class="navList">
-<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
+<li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
 <li><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
 </ul>
 <ul class="navList">

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html
new file mode 100644
index 0000000..edcd7f1
--- /dev/null
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc -->
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Uses of Class org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging (Apache HBase 3.0.0-SNAPSHOT Test API)</title>
+<link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style">
+<script type="text/javascript" src="../../../../../../../script.js"></script>
+</head>
+<body>
+<script type="text/javascript"><!--
+    try {
+        if (location.href.indexOf('is-external=true') == -1) {
+            parent.document.title="Uses of Class org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging (Apache HBase 3.0.0-SNAPSHOT Test API)";
+        }
+    }
+    catch(err) {
+    }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar.top">
+<!--   -->
+</a>
+<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
+<a name="navbar.top.firstrow">
+<!--   -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../../../../../../../overview-summary.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li><a href="../../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">Class</a></li>
+<li class="navBarCell1Rev">Use</li>
+<li><a href="../../../../../../../overview-tree.html">Tree</a></li>
+<li><a href="../../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="../../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html" target="_top">Frames</a></li>
+<li><a href="TestModifyTableWhileMerging.html" target="_top">No&nbsp;Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+  allClassesLink = document.getElementById("allclasses_navbar_top");
+  if(window==top) {
+    allClassesLink.style.display = "block";
+  }
+  else {
+    allClassesLink.style.display = "none";
+  }
+  //-->
+</script>
+</div>
+<a name="skip.navbar.top">
+<!--   -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h2 title="Uses of Class org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging" class="title">Uses of Class<br>org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging</h2>
+</div>
+<div class="classUseContainer">No usage of org.apache.hadoop.hbase.master.assignment.TestModifyTableWhileMerging</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar.bottom">
+<!--   -->
+</a>
+<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
+<a name="navbar.bottom.firstrow">
+<!--   -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../../../../../../../overview-summary.html">Overview</a></li>
+<li><a href="../package-summary.html">Package</a></li>
+<li><a href="../../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">Class</a></li>
+<li class="navBarCell1Rev">Use</li>
+<li><a href="../../../../../../../overview-tree.html">Tree</a></li>
+<li><a href="../../../../../../../deprecated-list.html">Deprecated</a></li>
+<li><a href="../../../../../../../index-all.html">Index</a></li>
+<li><a href="../../../../../../../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="../../../../../../../index.html?org/apache/hadoop/hbase/master/assignment/class-use/TestModifyTableWhileMerging.html" target="_top">Frames</a></li>
+<li><a href="TestModifyTableWhileMerging.html" target="_top">No&nbsp;Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+  allClassesLink = document.getElementById("allclasses_navbar_bottom");
+  if(window==top) {
+    allClassesLink.style.display = "block";
+  }
+  else {
+    allClassesLink.style.display = "none";
+  }
+  //-->
+</script>
+</div>
+<a name="skip.navbar.bottom">
+<!--   -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+<p class="legalCopy"><small>Copyright &#169; 2007&#x2013;2018 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-frame.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-frame.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-frame.html
index 7058eba..03bef82 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-frame.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-frame.html
@@ -27,6 +27,7 @@
 <li><a href="TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestMasterAbortWhileMergingTable</a></li>
 <li><a href="TestMasterAbortWhileMergingTable.MergeRegionObserver.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestMasterAbortWhileMergingTable.MergeRegionObserver</a></li>
 <li><a href="TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestMergeTableRegionsProcedure</a></li>
+<li><a href="TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestModifyTableWhileMerging</a></li>
 <li><a href="TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestRegionMoveAndAbandon</a></li>
 <li><a href="TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestRegionStates</a></li>
 <li><a href="TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment" target="classFrame">TestRogueRSAssignment</a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-summary.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-summary.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-summary.html
index 6963332..df044ec 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-summary.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-summary.html
@@ -140,26 +140,30 @@
 <td class="colLast">&nbsp;</td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment">TestModifyTableWhileMerging</a></td>
+<td class="colLast">&nbsp;</td>
+</tr>
+<tr class="altColor">
 <td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionMoveAndAbandon</a></td>
 <td class="colLast">
 <div class="block">Testcase for HBASE-20792.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRegionStates</a></td>
 <td class="colLast">&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment">TestRogueRSAssignment</a></td>
 <td class="colLast">
 <div class="block">Tests to verify master/ assignment manager functionality against rogue RS</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestSplitTableRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TestSplitTableRegionProcedure</a></td>
 <td class="colLast">&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestUnexpectedStateException.html" title="class in org.apache.hadoop.hbase.master.assignment">TestUnexpectedStateException</a></td>
 <td class="colLast">
 <div class="block">Tests for HBASE-18408 "AM consumes CPU and fills up the logs really fast when there is no RS to

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
----------------------------------------------------------------------
diff --git a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
index cd55683..0b58ba3 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/master/assignment/package-tree.html
@@ -122,6 +122,7 @@
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestMasterAbortWhileMergingTable</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMasterAbortWhileMergingTable.MergeRegionObserver.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestMasterAbortWhileMergingTable.MergeRegionObserver</span></a> (implements org.apache.hadoop.hbase.coprocessor.MasterCoprocessor, org.apache.hadoop.hbase.coprocessor.MasterObserver)</li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestMergeTableRegionsProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestMergeTableRegionsProcedure</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestModifyTableWhileMerging.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestModifyTableWhileMerging</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionMoveAndAbandon.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestRegionMoveAndAbandon</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestRegionStates</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.assignment.<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TestRogueRSAssignment.html" title="class in org.apache.hadoop.hbase.master.assignment"><span class="typeNameLink">TestRogueRSAssignment</span></a></li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 b11dae0..3d372b1 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -576,15 +576,15 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true" title="class or interface in java.io">Serializable</a>)
 <ul>
-<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.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/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/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/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/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/HBaseClusterManager.CommandProvider.Operation.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.CommandProvider.Operation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.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/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/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/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 ca2f47e..fbff915 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -205,9 +205,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.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/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>
 </ul>
 </li>
 </ul>


[25/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
index 4b73973..e50237f 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
@@ -887,7 +887,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsOfTable</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.686">getRegionsOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;table,
+<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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.692">getRegionsOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;table,
                                           boolean&nbsp;offline)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -901,7 +901,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsOfTable</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.695">getRegionsOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;table,
+<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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.701">getRegionsOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;table,
                                            <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html?is-external=true" title="class or interface in java.util.function">Predicate</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&gt;&nbsp;filter)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -917,7 +917,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>include</h4>
-<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.706">include</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;node,
+<pre>boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.712">include</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;node,
                 boolean&nbsp;offline)</pre>
 <div class="block">Utility. Whether to include region in list of regions. Default is to
  weed out split and offline regions.</div>
@@ -934,7 +934,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getServerRegionInfoSet</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.722">getServerRegionInfoSet</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.728">getServerRegionInfoSet</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Returns the set of regions hosted by the specified server</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -950,7 +950,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setServerState</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.737">setServerState</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.743">setServerState</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                             <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html" title="enum in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerState</a>&nbsp;state)</pre>
 </li>
 </ul>
@@ -960,7 +960,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>metaLogSplitting</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.748">metaLogSplitting</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.754">metaLogSplitting</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Call this when we start meta log splitting a crashed Server.</div>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -974,7 +974,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>metaLogSplit</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.756">metaLogSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.762">metaLogSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Called after we've split the meta logs on a crashed Server.</div>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -988,7 +988,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>logSplitting</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.764">logSplitting</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.770">logSplitting</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Call this when we start log splitting for a crashed Server.</div>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -1002,7 +1002,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>logSplit</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.772">logSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.778">logSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Called after we've split all logs on a crashed Server.</div>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -1016,7 +1016,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionState</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.776">updateRegionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.782">updateRegionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                               <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;state)</pre>
 </li>
 </ul>
@@ -1026,7 +1026,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAssignedRegions</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.786">getAssignedRegions</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/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.792">getAssignedRegions</a>()</pre>
 </li>
 </ul>
 <a name="isRegionInState-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State...-">
@@ -1035,7 +1035,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionInState</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.796">isRegionInState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.802">isRegionInState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                                <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>...&nbsp;state)</pre>
 </li>
 </ul>
@@ -1045,7 +1045,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionOnline</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.806">isRegionOnline</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.812">isRegionOnline</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="isRegionOffline-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1054,7 +1054,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionOffline</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.813">isRegionOffline</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.819">isRegionOffline</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>True if region is offline (In OFFLINE or CLOSED state).</dd>
@@ -1067,7 +1067,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getSnapShotOfAssignment</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="../../../../../../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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.817">getSnapShotOfAssignment</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionI
 nfo</a>&gt;&nbsp;regions)</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="../../../../../../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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.823">getSnapShotOfAssignment</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionI
 nfo</a>&gt;&nbsp;regions)</pre>
 </li>
 </ul>
 <a name="getRegionAssignments--">
@@ -1076,7 +1076,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionAssignments</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="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.839">getRegionAssignments</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="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.845">getRegionAssignments</a>()</pre>
 </li>
 </ul>
 <a name="getRegionByStateOfTable-org.apache.hadoop.hbase.TableName-">
@@ -1085,7 +1085,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionByStateOfTable</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="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.847">getRegionByStateOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</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="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</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;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.853">getRegionByStateOfTable</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
 </li>
 </ul>
 <a name="getRegionServerOfRegion-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1094,7 +1094,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionServerOfRegion</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.863">getRegionServerOfRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.869">getRegionServerOfRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="getAssignmentsByTable-boolean-">
@@ -1103,7 +1103,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAssignmentsByTable</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="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</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;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.882">getAssignmentsByTable</a>(boolean&nbsp;forceByClus
 ter)</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="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</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;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.888">getAssignmentsByTable</a>(boolean&nbsp;forceByClus
 ter)</pre>
 <div class="block">This is an EXPENSIVE clone.  Cloning though is the safest thing to do.
  Can't let out original since it can change and at least the load balancer
  wants to iterate this exported list.  We need to synchronize on regions
@@ -1122,7 +1122,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAssignmentsByTable</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="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</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;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.899">getAssignmentsByTable</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="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</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;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.905">getAssignmentsByTable</a>()</pre>
 </li>
 </ul>
 <a name="addRegionInTransition-org.apache.hadoop.hbase.master.assignment.RegionStates.RegionStateNode-org.apache.hadoop.hbase.master.assignment.RegionTransitionProcedure-">
@@ -1131,7 +1131,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addRegionInTransition</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.935">addRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode,
+<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.941">addRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode,
                                         <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionTransitionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionTransitionProcedure</a>&nbsp;procedure)</pre>
 </li>
 </ul>
@@ -1141,7 +1141,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegionInTransition</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.943">removeRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode,
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.949">removeRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode,
                                         <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionTransitionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionTransitionProcedure</a>&nbsp;procedure)</pre>
 </li>
 </ul>
@@ -1151,7 +1151,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRegionsInTransition</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.949">hasRegionsInTransition</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.955">hasRegionsInTransition</a>()</pre>
 </li>
 </ul>
 <a name="isRegionInTransition-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1160,7 +1160,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionInTransition</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.953">isRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.959">isRegionInTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="getRegionTransitionProcedure-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1169,7 +1169,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionTransitionProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionTransitionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionTransitionProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.961">getRegionTransitionProcedure</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionTransitionProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionTransitionProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.967">getRegionTransitionProcedure</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>If a procedure-in-transition for <code>hri</code>, return it else null.</dd>
@@ -1182,7 +1182,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionTransitionState</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.967">getRegionTransitionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.973">getRegionTransitionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
 </li>
 </ul>
 <a name="getRegionsInTransition--">
@@ -1191,7 +1191,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsInTransition</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/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.976">getRegionsInTransition</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/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.982">getRegionsInTransition</a>()</pre>
 </li>
 </ul>
 <a name="getRegionsInTransitionCount--">
@@ -1200,7 +1200,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsInTransitionCount</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.983">getRegionsInTransitionCount</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.989">getRegionsInTransitionCount</a>()</pre>
 <div class="block">Get the number of regions in transition.</div>
 </li>
 </ul>
@@ -1210,7 +1210,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsStateInTransition</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/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.987">getRegionsStateInTransition</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/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.993">getRegionsStateInTransition</a>()</pre>
 </li>
 </ul>
 <a name="getRegionsInTransitionOrderedByTimestamp--">
@@ -1219,7 +1219,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsInTransitionOrderedByTimestamp</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html?is-external=true" title="class or interface in java.util">SortedSet</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.995">getRegionsInTransitionOrderedByTimestamp</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html?is-external=true" title="class or interface in java.util">SortedSet</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1001">getRegionsInTransitionOrderedByTimestamp</a>()</pre>
 </li>
 </ul>
 <a name="addToOfflineRegions-org.apache.hadoop.hbase.master.assignment.RegionStates.RegionStateNode-">
@@ -1228,7 +1228,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addToOfflineRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1007">addToOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1013">addToOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
 <a name="removeFromOfflineRegions-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1237,7 +1237,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeFromOfflineRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1013">removeFromOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1019">removeFromOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="addToFailedOpen-org.apache.hadoop.hbase.master.assignment.RegionStates.RegionStateNode-">
@@ -1246,7 +1246,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addToFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1055">addToFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1061">addToFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
 <a name="getFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1255,7 +1255,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1066">getFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1072">getFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="removeFromFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1264,7 +1264,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeFromFailedOpen</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1070">removeFromFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1076">removeFromFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="getRegionFailedOpen--">
@@ -1273,7 +1273,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionFailedOpen</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/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1074">getRegionFailedOpen</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/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1080">getRegionFailedOpen</a>()</pre>
 </li>
 </ul>
 <a name="getOrCreateServer-org.apache.hadoop.hbase.ServerName-">
@@ -1282,7 +1282,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrCreateServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1093">getOrCreateServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1099">getOrCreateServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Be judicious calling this method. Do it on server register ONLY otherwise
  you could mess up online server accounting. TOOD: Review usage and convert
  to <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#getServerNode-org.apache.hadoop.hbase.ServerName-"><code>getServerNode(ServerName)</code></a> where we can.</div>
@@ -1294,7 +1294,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeServer</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1103">removeServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1109">removeServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
 <a name="getServerNode-org.apache.hadoop.hbase.ServerName-">
@@ -1303,7 +1303,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getServerNode</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1107">getServerNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1113">getServerNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
 <a name="getAverageLoad--">
@@ -1312,7 +1312,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAverageLoad</h4>
-<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1111">getAverageLoad</a>()</pre>
+<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1117">getAverageLoad</a>()</pre>
 </li>
 </ul>
 <a name="addRegionToServer-org.apache.hadoop.hbase.master.assignment.RegionStates.RegionStateNode-">
@@ -1321,7 +1321,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addRegionToServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1121">addRegionToServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1127">addRegionToServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
 <a name="removeRegionFromServer-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.master.assignment.RegionStates.RegionStateNode-">
@@ -1330,7 +1330,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegionFromServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1127">removeRegionFromServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1133">removeRegionFromServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                                            <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
@@ -1340,7 +1340,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionNamesToString</h4>
-<pre>public static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1137">regionNamesToString</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;byte[]&gt;&nbsp;regions)</pre>
+<pre>public static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.1143">regionNamesToString</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;byte[]&gt;&nbsp;regions)</pre>
 </li>
 </ul>
 </li>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
index 1799704..abd92a9 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
@@ -198,8 +198,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.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.Type.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BaseLoadBalancer.Cluster.Action.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BaseLoadBalancer.Cluster.LocalityType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.Cluster.Action.Type.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BaseLoadBalancer.Cluster.Action.Type</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 f053603..ad7c72c 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
@@ -349,10 +349,10 @@
 <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.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/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/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/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/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 d3f7afa..44286ce 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
@@ -216,10 +216,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.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/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/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/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">TableProcedureInterface.TableOperationType</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>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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/9cc58aff/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 defae87..1039401 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/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/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/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/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/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/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/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/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/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/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/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/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/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/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/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/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/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
index 6c4852a..81c701f 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
@@ -127,7 +127,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.159">ProcedureExecutor.CompletedProcedureCleaner</a>&lt;TEnvironment&gt;
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.160">ProcedureExecutor.CompletedProcedureCleaner</a>&lt;TEnvironment&gt;
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;TEnvironment&gt;</pre>
 <div class="block">Internal cleaner that removes the completed procedure results after a TTL.
  NOTE: This is a special case handled in timeoutLoop().
@@ -317,7 +317,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <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/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.161">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.162">LOG</a></pre>
 </li>
 </ul>
 <a name="CLEANER_INTERVAL_CONF_KEY">
@@ -326,7 +326,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>CLEANER_INTERVAL_CONF_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.163">CLEANER_INTERVAL_CONF_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.164">CLEANER_INTERVAL_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.CLEANER_INTERVAL_CONF_KEY">Constant Field Values</a></dd>
@@ -339,7 +339,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_CLEANER_INTERVAL</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.164">DEFAULT_CLEANER_INTERVAL</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.165">DEFAULT_CLEANER_INTERVAL</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.DEFAULT_CLEANER_INTERVAL">Constant Field Values</a></dd>
@@ -352,7 +352,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>EVICT_TTL_CONF_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.166">EVICT_TTL_CONF_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.167">EVICT_TTL_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.EVICT_TTL_CONF_KEY">Constant Field Values</a></dd>
@@ -365,7 +365,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_EVICT_TTL</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.167">DEFAULT_EVICT_TTL</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.168">DEFAULT_EVICT_TTL</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.DEFAULT_EVICT_TTL">Constant Field Values</a></dd>
@@ -378,7 +378,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>EVICT_ACKED_TTL_CONF_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.169">EVICT_ACKED_TTL_CONF_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.170">EVICT_ACKED_TTL_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.EVICT_ACKED_TTL_CONF_KEY">Constant Field Values</a></dd>
@@ -391,7 +391,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_ACKED_EVICT_TTL</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.170">DEFAULT_ACKED_EVICT_TTL</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.171">DEFAULT_ACKED_EVICT_TTL</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.DEFAULT_ACKED_EVICT_TTL">Constant Field Values</a></dd>
@@ -404,7 +404,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>BATCH_SIZE_CONF_KEY</h4>
-<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.172">BATCH_SIZE_CONF_KEY</a></pre>
+<pre>private static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.173">BATCH_SIZE_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.BATCH_SIZE_CONF_KEY">Constant Field Values</a></dd>
@@ -417,7 +417,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_BATCH_SIZE</h4>
-<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.173">DEFAULT_BATCH_SIZE</a></pre>
+<pre>private static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.174">DEFAULT_BATCH_SIZE</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CompletedProcedureCleaner.DEFAULT_BATCH_SIZE">Constant Field Values</a></dd>
@@ -430,7 +430,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>completed</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/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.175">completed</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/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.176">completed</a></pre>
 </li>
 </ul>
 <a name="nonceKeysToProcIdsMap">
@@ -439,7 +439,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>nonceKeysToProcIdsMap</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="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.176">nonceKeysToProcIdsMap</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="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.177">nonceKeysToProcIdsMap</a></pre>
 </li>
 </ul>
 <a name="store">
@@ -448,7 +448,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockList">
 <li class="blockList">
 <h4>store</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.177">store</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.178">store</a></pre>
 </li>
 </ul>
 <a name="conf">
@@ -457,7 +457,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockListLast">
 <li class="blockList">
 <h4>conf</h4>
-<pre>private&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.178">conf</a></pre>
+<pre>private&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.179">conf</a></pre>
 </li>
 </ul>
 </li>
@@ -474,7 +474,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockListLast">
 <li class="blockList">
 <h4>CompletedProcedureCleaner</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.180">CompletedProcedureCleaner</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.181">CompletedProcedureCleaner</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                                  <a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a>&nbsp;store,
                                  <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/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&gt;&gt;&nbsp;completedMap,
                                  <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/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;nonceKeysToProcIdsMap)</pre>
@@ -496,7 +496,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMe
 <ul class="blockListLast">
 <li class="blockList">
 <h4>periodicExecute</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.192">periodicExecute</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&nbsp;env)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html#line.193">periodicExecute</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&nbsp;env)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html#periodicExecute-TEnvironment-">periodicExecute</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html" title="type parameter in ProcedureExecutor.CompletedProcedureCleaner">TEnvironment</a>&gt;</code></dd>


[22/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
index dff3871..2a87a4a 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
@@ -69,13 +69,13 @@
 <ul class="subNavList">
 <li>Summary:&nbsp;</li>
 <li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
 <li><a href="#methods.inherited.from.class.java.lang.Throwable">Method</a></li>
 </ul>
 <ul class="subNavList">
 <li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
 <li>Method</li>
 </ul>
@@ -128,8 +128,7 @@
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
- @InterfaceStability.Stable
-public class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#line.26">ProcedureSuspendedException</a>
+public class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#line.23">ProcedureSuspendedException</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureException</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
@@ -141,6 +140,25 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExce
 <div class="summary">
 <ul class="blockList">
 <li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field.summary">
+<!--   -->
+</a>
+<h3>Field Summary</h3>
+<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>private static long</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#serialVersionUID">serialVersionUID</a></span></code>&nbsp;</td>
+</tr>
+</table>
+</li>
+</ul>
 <!-- ======== CONSTRUCTOR SUMMARY ======== -->
 <ul class="blockList">
 <li class="blockList"><a name="constructor.summary">
@@ -193,6 +211,27 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExce
 <div class="details">
 <ul class="blockList">
 <li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field.detail">
+<!--   -->
+</a>
+<h3>Field Detail</h3>
+<a name="serialVersionUID">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>serialVersionUID</h4>
+<pre>private static final&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html#line.25">serialVersionUID</a></pre>
+<dl>
+<dt><span class="seeLabel">See Also:</span></dt>
+<dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException.serialVersionUID">Constant Field Values</a></dd>
+</dl>
+</li>
+</ul>
+</li>
+</ul>
 <!-- ========= CONSTRUCTOR DETAIL ======== -->
 <ul class="blockList">
 <li class="blockList"><a name="constructor.detail">
@@ -277,13 +316,13 @@ extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExce
 <ul class="subNavList">
 <li>Summary:&nbsp;</li>
 <li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
 <li><a href="#methods.inherited.from.class.java.lang.Throwable">Method</a></li>
 </ul>
 <ul class="subNavList">
 <li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
 <li>Method</li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index 22decce..f83465c 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -216,11 +216,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.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockedResourceType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockedResourceType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 6a35e0b..e63e2a4 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/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/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/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/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/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/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/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/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 87957f4..482efa8 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -704,20 +704,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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/SplitLogWorker.TaskExecutor.Status.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">SplitLogWorker.TaskExecutor.Status</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/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/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/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/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/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 6851ee1..858ccf6 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/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/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/ScanQueryMatcher.MatchCode.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">ScanQueryMatcher.MatchCode</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 c20ff47..034077c 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.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>
+<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>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html b/devapidocs/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
index 6de3f87..9538265 100644
--- a/devapidocs/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
+++ b/devapidocs/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
@@ -727,7 +727,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/coprocessor/MasterCop
 <ul class="blockList">
 <li class="blockList">
 <h4>checkPermission</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html#line.545">checkPermission</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;request)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html#line.547">checkPermission</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;request)
                      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>
@@ -741,7 +741,7 @@ implements <a href="../../../../../org/apache/hadoop/hbase/coprocessor/MasterCop
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getActiveUser</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/security/User.html" title="class in org.apache.hadoop.hbase.security">User</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html#line.554">getActiveUser</a>()
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/security/User.html" title="class in org.apache.hadoop.hbase.security">User</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html#line.556">getActiveUser</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>
 <div class="block">Returns the active user to which authorization checks should be applied.
  If we are in the context of an RPC call, the remote user is used,

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 f594c43..8051208 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/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
-<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>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 67b7e3a..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/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/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/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>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
index 81a90a9..2cef8bd 100644
--- a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
@@ -199,9 +199,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.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftServerRunner.ImplType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftServerRunner.ImplType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/util/IdLock.Entry.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/IdLock.Entry.html b/devapidocs/org/apache/hadoop/hbase/util/IdLock.Entry.html
index 72fe912..967a2e7 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/IdLock.Entry.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/IdLock.Entry.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.46">IdLock.Entry</a>
+<pre>public static final class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.45">IdLock.Entry</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 <div class="block">An entry returned to the client as a lock object</div>
 </li>
@@ -212,7 +212,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>id</h4>
-<pre>private final&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.47">id</a></pre>
+<pre>private final&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.46">id</a></pre>
 </li>
 </ul>
 <a name="numWaiters">
@@ -221,7 +221,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>numWaiters</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.48">numWaiters</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.47">numWaiters</a></pre>
 </li>
 </ul>
 <a name="locked">
@@ -230,7 +230,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>locked</h4>
-<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.49">locked</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.48">locked</a></pre>
 </li>
 </ul>
 </li>
@@ -247,7 +247,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>Entry</h4>
-<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.51">Entry</a>(long&nbsp;id)</pre>
+<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html#line.50">Entry</a>(long&nbsp;id)</pre>
 </li>
 </ul>
 </li>
@@ -264,7 +264,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <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/util/IdLock.Entry.html#line.56">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/util/IdLock.Entry.html#line.55">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>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/util/IdLock.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/IdLock.html b/devapidocs/org/apache/hadoop/hbase/util/IdLock.html
index 2c17124..99efa36 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/IdLock.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/IdLock.html
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.43">IdLock</a>
+public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.42">IdLock</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 <div class="block">Allows multiple concurrent clients to lock on a numeric id with a minimal
  memory overhead. The intended usage is as follows:
@@ -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>map</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.62">map</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.61">map</a></pre>
 </li>
 </ul>
 </li>
@@ -267,7 +267,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>IdLock</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.43">IdLock</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.42">IdLock</a>()</pre>
 </li>
 </ul>
 </li>
@@ -284,7 +284,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLockEntry</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.72">getLockEntry</a>(long&nbsp;id)
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.71">getLockEntry</a>(long&nbsp;id)
                           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">Blocks until the lock corresponding to the given id is acquired.</div>
 <dl>
@@ -304,7 +304,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>releaseLockEntry</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.108">releaseLockEntry</a>(<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&nbsp;entry)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.107">releaseLockEntry</a>(<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.Entry.html" title="class in org.apache.hadoop.hbase.util">IdLock.Entry</a>&nbsp;entry)</pre>
 <div class="block">Must be called in a finally block to decrease the internal counter and
  remove the monitor object for the given id if the caller is the last
  client.</div>
@@ -320,7 +320,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>assertMapEmpty</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.120">assertMapEmpty</a>()</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.119">assertMapEmpty</a>()</pre>
 <div class="block">For testing</div>
 </li>
 </ul>
@@ -330,7 +330,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>waitForWaiters</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.125">waitForWaiters</a>(long&nbsp;id,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/IdLock.html#line.124">waitForWaiters</a>(long&nbsp;id,
                            int&nbsp;numWaiters)
                     throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
 <dl>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/util/class-use/IdLock.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/class-use/IdLock.html b/devapidocs/org/apache/hadoop/hbase/util/class-use/IdLock.html
index acf1835..d874e7a 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/class-use/IdLock.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/class-use/IdLock.html
@@ -98,6 +98,10 @@
 <td class="colLast">&nbsp;</td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><a href="#org.apache.hadoop.hbase.procedure2">org.apache.hadoop.hbase.procedure2</a></td>
+<td class="colLast">&nbsp;</td>
+</tr>
+<tr class="altColor">
 <td class="colFirst"><a href="#org.apache.hadoop.hbase.regionserver">org.apache.hadoop.hbase.regionserver</a></td>
 <td class="colLast">&nbsp;</td>
 </tr>
@@ -163,6 +167,24 @@
 </tbody>
 </table>
 </li>
+<li class="blockList"><a name="org.apache.hadoop.hbase.procedure2">
+<!--   -->
+</a>
+<h3>Uses of <a href="../../../../../../org/apache/hadoop/hbase/util/IdLock.html" title="class in org.apache.hadoop.hbase.util">IdLock</a> in <a href="../../../../../../org/apache/hadoop/hbase/procedure2/package-summary.html">org.apache.hadoop.hbase.procedure2</a></h3>
+<table class="useSummary" border="0" cellpadding="3" cellspacing="0" summary="Use table, listing fields, and an explanation">
+<caption><span>Fields in <a href="../../../../../../org/apache/hadoop/hbase/procedure2/package-summary.html">org.apache.hadoop.hbase.procedure2</a> declared as <a href="../../../../../../org/apache/hadoop/hbase/util/IdLock.html" title="class in org.apache.hadoop.hbase.util">IdLock</a></span><span class="tabEnd">&nbsp;</span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tbody>
+<tr class="altColor">
+<td class="colFirst"><code>private <a href="../../../../../../org/apache/hadoop/hbase/util/IdLock.html" title="class in org.apache.hadoop.hbase.util">IdLock</a></code></td>
+<td class="colLast"><span class="typeNameLabel">ProcedureExecutor.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#procExecutionLock">procExecutionLock</a></span></code>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+</li>
 <li class="blockList"><a name="org.apache.hadoop.hbase.regionserver">
 <!--   -->
 </a>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 398cbf4..172ee3d 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
@@ -514,14 +514,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.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/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/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/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/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/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.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/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.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
 </ul>
 </li>
 </ul>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/util/package-use.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/util/package-use.html b/devapidocs/org/apache/hadoop/hbase/util/package-use.html
index 33b6f87..a2f0b4e 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-use.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-use.html
@@ -1148,6 +1148,12 @@ service.</div>
 </tr>
 <tbody>
 <tr class="altColor">
+<td class="colOne"><a href="../../../../../org/apache/hadoop/hbase/util/class-use/IdLock.html#org.apache.hadoop.hbase.procedure2">IdLock</a>
+<div class="block">Allows multiple concurrent clients to lock on a numeric id with a minimal
+ memory overhead.</div>
+</td>
+</tr>
+<tr class="rowColor">
 <td class="colOne"><a href="../../../../../org/apache/hadoop/hbase/util/class-use/NonceKey.html#org.apache.hadoop.hbase.procedure2">NonceKey</a>
 <div class="block">This implementation is not smart and just treats nonce group and nonce as random bits.</div>
 </td>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/serialized-form.html
----------------------------------------------------------------------
diff --git a/devapidocs/serialized-form.html b/devapidocs/serialized-form.html
index 698a2f9..e0bd1b6 100644
--- a/devapidocs/serialized-form.html
+++ b/devapidocs/serialized-form.html
@@ -1325,6 +1325,10 @@
 <!--   -->
 </a>
 <h3>Class <a href="org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException</a> extends <a href="org/apache/hadoop/hbase/procedure2/ProcedureException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureException</a> implements Serializable</h3>
+<dl class="nameValue">
+<dt>serialVersionUID:</dt>
+<dd>-8328419627678496269L</dd>
+</dl>
 </li>
 <li class="blockList"><a name="org.apache.hadoop.hbase.procedure2.ProcedureYieldException">
 <!--   -->

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/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 67dc261..1580fa4 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/Version.html
@@ -16,11 +16,11 @@
 <span class="sourceLineNo">008</span>@InterfaceAudience.Private<a name="line.8"></a>
 <span class="sourceLineNo">009</span>public class Version {<a name="line.9"></a>
 <span class="sourceLineNo">010</span>  public static final String version = "3.0.0-SNAPSHOT";<a name="line.10"></a>
-<span class="sourceLineNo">011</span>  public static final String revision = "a392c017ed05c541403307e7fc75fbad38acff4a";<a name="line.11"></a>
+<span class="sourceLineNo">011</span>  public static final String revision = "7178a98258dbb28496c2c4f3fbbf8e552ead8bdb";<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 Jul 26 14:39:43 UTC 2018";<a name="line.13"></a>
+<span class="sourceLineNo">013</span>  public static final String date = "Fri Jul 27 14:40:32 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 = "9d54db4d371ad5e7218c7c216677d202";<a name="line.15"></a>
+<span class="sourceLineNo">015</span>  public static final String srcChecksum = "a923cfae6952ac8068c6f7b0905a56a7";<a name="line.15"></a>
 <span class="sourceLineNo">016</span>}<a name="line.16"></a>
 
 


[19/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateNode.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode != null ? o

<TRUNCATED>

[06/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerMonitor.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line.482"></a>
-<span class="sourceLineNo">4

<TRUNCATED>

[13/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.html
index a706f1c..e5072cf 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.html
@@ -132,7 +132,7 @@
 <span class="sourceLineNo">124</span>  @Override<a name="line.124"></a>
 <span class="sourceLineNo">125</span>  protected void rollbackState(MasterProcedureEnv env, ReopenTableRegionsState state)<a name="line.125"></a>
 <span class="sourceLineNo">126</span>      throws IOException, InterruptedException {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>    throw new UnsupportedOperationException();<a name="line.127"></a>
+<span class="sourceLineNo">127</span>    throw new UnsupportedOperationException("unhandled state=" + state);<a name="line.127"></a>
 <span class="sourceLineNo">128</span>  }<a name="line.128"></a>
 <span class="sourceLineNo">129</span><a name="line.129"></a>
 <span class="sourceLineNo">130</span>  @Override<a name="line.130"></a>


[20/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode != nul

<TRUNCATED>

[18/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateStampComparator.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateStampComparator.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateStampComparator.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateStampComparator.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionStateStampComparator.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="so

<TRUNCATED>

[12/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureCleaner.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinish

<TRUNCATED>

[08/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinish

<TRUNCATED>

[16/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerState.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode != null ? oldNode : newNode;<a 

<TRUNCATED>

[04/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line.482"></a>
-<span class="sourceLineNo">483</span>          parent.incChildrenLatch();<a name="line.483"></a>
-

<TRUNCATED>

[09/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
index 1aed387..22f68b3 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.KeepAliveWorkerThread.html
@@ -55,1901 +55,1905 @@
 <span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.procedure2.util.StringUtils;<a name="line.47"></a>
 <span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.security.User;<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.hadoop.hbase.util.NonceKey;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.slf4j.Logger;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.slf4j.LoggerFactory;<a name="line.54"></a>
-<span class="sourceLineNo">055</span><a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.57"></a>
-<span class="sourceLineNo">058</span><a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.59"></a>
-<span class="sourceLineNo">060</span><a name="line.60"></a>
-<span class="sourceLineNo">061</span>/**<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * Thread Pool that executes the submitted procedures.<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * The executor has a ProcedureStore associated.<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * procedures are resumed and the once failed will be rolledback.<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * check for the finished state via isFinished(procId)<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * and get the result via getResult(procId)<a name="line.72"></a>
-<span class="sourceLineNo">073</span> */<a name="line.73"></a>
-<span class="sourceLineNo">074</span>@InterfaceAudience.Private<a name="line.74"></a>
-<span class="sourceLineNo">075</span>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.76"></a>
-<span class="sourceLineNo">077</span><a name="line.77"></a>
-<span class="sourceLineNo">078</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.78"></a>
-<span class="sourceLineNo">079</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.79"></a>
-<span class="sourceLineNo">080</span><a name="line.80"></a>
-<span class="sourceLineNo">081</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.81"></a>
-<span class="sourceLineNo">082</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.82"></a>
-<span class="sourceLineNo">083</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.83"></a>
-<span class="sourceLineNo">084</span><a name="line.84"></a>
-<span class="sourceLineNo">085</span>  Testing testing = null;<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static class Testing {<a name="line.86"></a>
-<span class="sourceLineNo">087</span>    protected boolean killIfSuspended = false;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.91"></a>
-<span class="sourceLineNo">092</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        this.killBeforeStoreUpdate = !kill;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>      return kill;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    }<a name="line.98"></a>
-<span class="sourceLineNo">099</span><a name="line.99"></a>
-<span class="sourceLineNo">100</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.100"></a>
-<span class="sourceLineNo">101</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    }<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  }<a name="line.103"></a>
-<span class="sourceLineNo">104</span><a name="line.104"></a>
-<span class="sourceLineNo">105</span>  public interface ProcedureExecutorListener {<a name="line.105"></a>
-<span class="sourceLineNo">106</span>    void procedureLoaded(long procId);<a name="line.106"></a>
-<span class="sourceLineNo">107</span>    void procedureAdded(long procId);<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    void procedureFinished(long procId);<a name="line.108"></a>
-<span class="sourceLineNo">109</span>  }<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    private long clientAckTime;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.115"></a>
-<span class="sourceLineNo">116</span>      this.procedure = procedure;<a name="line.116"></a>
-<span class="sourceLineNo">117</span>      clientAckTime = -1;<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    }<a name="line.118"></a>
-<span class="sourceLineNo">119</span><a name="line.119"></a>
-<span class="sourceLineNo">120</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>      return procedure;<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>    public boolean hasClientAckTime() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>      return clientAckTime != -1;<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    }<a name="line.126"></a>
-<span class="sourceLineNo">127</span><a name="line.127"></a>
-<span class="sourceLineNo">128</span>    public long getClientAckTime() {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>      return clientAckTime;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
-<span class="sourceLineNo">131</span><a name="line.131"></a>
-<span class="sourceLineNo">132</span>    public void setClientAckTime(long clientAckTime) {<a name="line.132"></a>
-<span class="sourceLineNo">133</span>      this.clientAckTime = clientAckTime;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>    }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.136"></a>
-<span class="sourceLineNo">137</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<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><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  /**<a name="line.142"></a>
-<span class="sourceLineNo">143</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.143"></a>
-<span class="sourceLineNo">144</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.144"></a>
-<span class="sourceLineNo">145</span>   *<a name="line.145"></a>
-<span class="sourceLineNo">146</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.146"></a>
-<span class="sourceLineNo">147</span>   * &lt;pre&gt;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>   *   procId = master.doOperation()<a name="line.148"></a>
-<span class="sourceLineNo">149</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.149"></a>
-<span class="sourceLineNo">150</span>   * &lt;/pre&gt;<a name="line.150"></a>
-<span class="sourceLineNo">151</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.151"></a>
-<span class="sourceLineNo">152</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.152"></a>
-<span class="sourceLineNo">153</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.153"></a>
-<span class="sourceLineNo">154</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.154"></a>
-<span class="sourceLineNo">155</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.155"></a>
-<span class="sourceLineNo">156</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.156"></a>
-<span class="sourceLineNo">157</span>   * the proc result the client will be able to get the result the next try.<a name="line.157"></a>
-<span class="sourceLineNo">158</span>   */<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.159"></a>
-<span class="sourceLineNo">160</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.161"></a>
-<span class="sourceLineNo">162</span><a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.163"></a>
-<span class="sourceLineNo">164</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.164"></a>
-<span class="sourceLineNo">165</span><a name="line.165"></a>
-<span class="sourceLineNo">166</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.167"></a>
-<span class="sourceLineNo">168</span><a name="line.168"></a>
-<span class="sourceLineNo">169</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.170"></a>
-<span class="sourceLineNo">171</span><a name="line.171"></a>
-<span class="sourceLineNo">172</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    private final ProcedureStore store;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    private Configuration conf;<a name="line.178"></a>
-<span class="sourceLineNo">179</span><a name="line.179"></a>
-<span class="sourceLineNo">180</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.180"></a>
-<span class="sourceLineNo">181</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      this.completed = completedMap;<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>      this.store = store;<a name="line.187"></a>
-<span class="sourceLineNo">188</span>      this.conf = conf;<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    }<a name="line.189"></a>
-<span class="sourceLineNo">190</span><a name="line.190"></a>
-<span class="sourceLineNo">191</span>    @Override<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.192"></a>
-<span class="sourceLineNo">193</span>      if (completed.isEmpty()) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>        if (LOG.isTraceEnabled()) {<a name="line.194"></a>
-<span class="sourceLineNo">195</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.195"></a>
-<span class="sourceLineNo">196</span>        }<a name="line.196"></a>
-<span class="sourceLineNo">197</span>        return;<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>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.200"></a>
-<span class="sourceLineNo">201</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.202"></a>
-<span class="sourceLineNo">203</span><a name="line.203"></a>
-<span class="sourceLineNo">204</span>      final long[] batchIds = new long[batchSize];<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      int batchCount = 0;<a name="line.205"></a>
-<span class="sourceLineNo">206</span><a name="line.206"></a>
-<span class="sourceLineNo">207</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.207"></a>
-<span class="sourceLineNo">208</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.208"></a>
-<span class="sourceLineNo">209</span>        completed.entrySet().iterator();<a name="line.209"></a>
-<span class="sourceLineNo">210</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.210"></a>
-<span class="sourceLineNo">211</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.211"></a>
-<span class="sourceLineNo">212</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.212"></a>
-<span class="sourceLineNo">213</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.213"></a>
-<span class="sourceLineNo">214</span><a name="line.214"></a>
-<span class="sourceLineNo">215</span>        // TODO: Select TTL based on Procedure type<a name="line.215"></a>
-<span class="sourceLineNo">216</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.216"></a>
-<span class="sourceLineNo">217</span>          // Failed procedures aren't persisted in WAL.<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.218"></a>
-<span class="sourceLineNo">219</span>            batchIds[batchCount++] = entry.getKey();<a name="line.219"></a>
-<span class="sourceLineNo">220</span>            if (batchCount == batchIds.length) {<a name="line.220"></a>
-<span class="sourceLineNo">221</span>              store.delete(batchIds, 0, batchCount);<a name="line.221"></a>
-<span class="sourceLineNo">222</span>              batchCount = 0;<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>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.225"></a>
-<span class="sourceLineNo">226</span>          if (nonceKey != null) {<a name="line.226"></a>
-<span class="sourceLineNo">227</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.227"></a>
-<span class="sourceLineNo">228</span>          }<a name="line.228"></a>
-<span class="sourceLineNo">229</span>          it.remove();<a name="line.229"></a>
-<span class="sourceLineNo">230</span>          LOG.trace("Evict completed {}", proc);<a name="line.230"></a>
-<span class="sourceLineNo">231</span>        }<a name="line.231"></a>
-<span class="sourceLineNo">232</span>      }<a name="line.232"></a>
-<span class="sourceLineNo">233</span>      if (batchCount &gt; 0) {<a name="line.233"></a>
-<span class="sourceLineNo">234</span>        store.delete(batchIds, 0, batchCount);<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>  }<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.240"></a>
-<span class="sourceLineNo">241</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.241"></a>
-<span class="sourceLineNo">242</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.242"></a>
-<span class="sourceLineNo">243</span>   */<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.248"></a>
-<span class="sourceLineNo">249</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.249"></a>
-<span class="sourceLineNo">250</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.250"></a>
-<span class="sourceLineNo">251</span>   */<a name="line.251"></a>
-<span class="sourceLineNo">252</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.257"></a>
-<span class="sourceLineNo">258</span>   */<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>  /**<a name="line.262"></a>
-<span class="sourceLineNo">263</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.263"></a>
-<span class="sourceLineNo">264</span>   * contains every root procedure.<a name="line.264"></a>
-<span class="sourceLineNo">265</span>   */<a name="line.265"></a>
-<span class="sourceLineNo">266</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.268"></a>
-<span class="sourceLineNo">269</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.269"></a>
-<span class="sourceLineNo">270</span><a name="line.270"></a>
-<span class="sourceLineNo">271</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.274"></a>
-<span class="sourceLineNo">275</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.275"></a>
-<span class="sourceLineNo">276</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * (Should be ok).<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   */<a name="line.278"></a>
-<span class="sourceLineNo">279</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.282"></a>
-<span class="sourceLineNo">283</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.283"></a>
-<span class="sourceLineNo">284</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.284"></a>
-<span class="sourceLineNo">285</span>   * (Should be ok).<a name="line.285"></a>
-<span class="sourceLineNo">286</span>   */<a name="line.286"></a>
-<span class="sourceLineNo">287</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<a name="line.287"></a>
-<span class="sourceLineNo">288</span><a name="line.288"></a>
-<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
-<span class="sourceLineNo">290</span>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.290"></a>
-<span class="sourceLineNo">291</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * (Should be ok).<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   */<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private int corePoolSize;<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  private int maxPoolSize;<a name="line.298"></a>
-<span class="sourceLineNo">299</span><a name="line.299"></a>
-<span class="sourceLineNo">300</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.303"></a>
-<span class="sourceLineNo">304</span>   */<a name="line.304"></a>
-<span class="sourceLineNo">305</span>  private final ProcedureScheduler scheduler;<a name="line.305"></a>
-<span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.310"></a>
-<span class="sourceLineNo">311</span>  private final TEnvironment environment;<a name="line.311"></a>
-<span class="sourceLineNo">312</span>  private final ProcedureStore store;<a name="line.312"></a>
-<span class="sourceLineNo">313</span><a name="line.313"></a>
-<span class="sourceLineNo">314</span>  private final boolean checkOwnerSet;<a name="line.314"></a>
-<span class="sourceLineNo">315</span><a name="line.315"></a>
-<span class="sourceLineNo">316</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.316"></a>
-<span class="sourceLineNo">317</span>      final ProcedureStore store) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    this.environment = environment;<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    this.scheduler = scheduler;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>    this.store = store;<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    this.conf = conf;<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    refreshConfiguration(conf);<a name="line.328"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.util.IdLock;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.util.NonceKey;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.util.Threads;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.slf4j.Logger;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.slf4j.LoggerFactory;<a name="line.55"></a>
+<span class="sourceLineNo">056</span><a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;<a name="line.58"></a>
+<span class="sourceLineNo">059</span><a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;<a name="line.60"></a>
+<span class="sourceLineNo">061</span><a name="line.61"></a>
+<span class="sourceLineNo">062</span>/**<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * Thread Pool that executes the submitted procedures.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * The executor has a ProcedureStore associated.<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * Each operation is logged and on restart the pending procedures are resumed.<a name="line.65"></a>
+<span class="sourceLineNo">066</span> *<a name="line.66"></a>
+<span class="sourceLineNo">067</span> * Unless the Procedure code throws an error (e.g. invalid user input)<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * the procedure will complete (at some point in time), On restart the pending<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * procedures are resumed and the once failed will be rolledback.<a name="line.69"></a>
+<span class="sourceLineNo">070</span> *<a name="line.70"></a>
+<span class="sourceLineNo">071</span> * The user can add procedures to the executor via submitProcedure(proc)<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * check for the finished state via isFinished(procId)<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * and get the result via getResult(procId)<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>public class ProcedureExecutor&lt;TEnvironment&gt; {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>  private static final Logger LOG = LoggerFactory.getLogger(ProcedureExecutor.class);<a name="line.77"></a>
+<span class="sourceLineNo">078</span><a name="line.78"></a>
+<span class="sourceLineNo">079</span>  public static final String CHECK_OWNER_SET_CONF_KEY = "hbase.procedure.check.owner.set";<a name="line.79"></a>
+<span class="sourceLineNo">080</span>  private static final boolean DEFAULT_CHECK_OWNER_SET = false;<a name="line.80"></a>
+<span class="sourceLineNo">081</span><a name="line.81"></a>
+<span class="sourceLineNo">082</span>  public static final String WORKER_KEEP_ALIVE_TIME_CONF_KEY =<a name="line.82"></a>
+<span class="sourceLineNo">083</span>      "hbase.procedure.worker.keep.alive.time.msec";<a name="line.83"></a>
+<span class="sourceLineNo">084</span>  private static final long DEFAULT_WORKER_KEEP_ALIVE_TIME = TimeUnit.MINUTES.toMillis(1);<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>  Testing testing = null;<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static class Testing {<a name="line.87"></a>
+<span class="sourceLineNo">088</span>    protected boolean killIfSuspended = false;<a name="line.88"></a>
+<span class="sourceLineNo">089</span>    protected boolean killBeforeStoreUpdate = false;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>    protected boolean toggleKillBeforeStoreUpdate = false;<a name="line.90"></a>
+<span class="sourceLineNo">091</span><a name="line.91"></a>
+<span class="sourceLineNo">092</span>    protected boolean shouldKillBeforeStoreUpdate() {<a name="line.92"></a>
+<span class="sourceLineNo">093</span>      final boolean kill = this.killBeforeStoreUpdate;<a name="line.93"></a>
+<span class="sourceLineNo">094</span>      if (this.toggleKillBeforeStoreUpdate) {<a name="line.94"></a>
+<span class="sourceLineNo">095</span>        this.killBeforeStoreUpdate = !kill;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>        LOG.warn("Toggle KILL before store update to: " + this.killBeforeStoreUpdate);<a name="line.96"></a>
+<span class="sourceLineNo">097</span>      }<a name="line.97"></a>
+<span class="sourceLineNo">098</span>      return kill;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>    }<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>    protected boolean shouldKillBeforeStoreUpdate(final boolean isSuspended) {<a name="line.101"></a>
+<span class="sourceLineNo">102</span>      return (isSuspended &amp;&amp; !killIfSuspended) ? false : shouldKillBeforeStoreUpdate();<a name="line.102"></a>
+<span class="sourceLineNo">103</span>    }<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  }<a name="line.104"></a>
+<span class="sourceLineNo">105</span><a name="line.105"></a>
+<span class="sourceLineNo">106</span>  public interface ProcedureExecutorListener {<a name="line.106"></a>
+<span class="sourceLineNo">107</span>    void procedureLoaded(long procId);<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    void procedureAdded(long procId);<a name="line.108"></a>
+<span class="sourceLineNo">109</span>    void procedureFinished(long procId);<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>  private static final class CompletedProcedureRetainer&lt;TEnvironment&gt; {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    private final Procedure&lt;TEnvironment&gt; procedure;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    private long clientAckTime;<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    public CompletedProcedureRetainer(Procedure&lt;TEnvironment&gt; procedure) {<a name="line.116"></a>
+<span class="sourceLineNo">117</span>      this.procedure = procedure;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>      clientAckTime = -1;<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    }<a name="line.119"></a>
+<span class="sourceLineNo">120</span><a name="line.120"></a>
+<span class="sourceLineNo">121</span>    public Procedure&lt;TEnvironment&gt; getProcedure() {<a name="line.121"></a>
+<span class="sourceLineNo">122</span>      return procedure;<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    }<a name="line.123"></a>
+<span class="sourceLineNo">124</span><a name="line.124"></a>
+<span class="sourceLineNo">125</span>    public boolean hasClientAckTime() {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      return clientAckTime != -1;<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    }<a name="line.127"></a>
+<span class="sourceLineNo">128</span><a name="line.128"></a>
+<span class="sourceLineNo">129</span>    public long getClientAckTime() {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>      return clientAckTime;<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>    public void setClientAckTime(long clientAckTime) {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      this.clientAckTime = clientAckTime;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span><a name="line.136"></a>
+<span class="sourceLineNo">137</span>    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {<a name="line.137"></a>
+<span class="sourceLineNo">138</span>      return (hasClientAckTime() &amp;&amp; (now - getClientAckTime()) &gt;= evictAckTtl) ||<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        (now - procedure.getLastUpdate()) &gt;= evictTtl;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    }<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  /**<a name="line.143"></a>
+<span class="sourceLineNo">144</span>   * Internal cleaner that removes the completed procedure results after a TTL.<a name="line.144"></a>
+<span class="sourceLineNo">145</span>   * NOTE: This is a special case handled in timeoutLoop().<a name="line.145"></a>
+<span class="sourceLineNo">146</span>   *<a name="line.146"></a>
+<span class="sourceLineNo">147</span>   * &lt;p&gt;Since the client code looks more or less like:<a name="line.147"></a>
+<span class="sourceLineNo">148</span>   * &lt;pre&gt;<a name="line.148"></a>
+<span class="sourceLineNo">149</span>   *   procId = master.doOperation()<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   *   while (master.getProcResult(procId) == ProcInProgress);<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * &lt;/pre&gt;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * The master should not throw away the proc result as soon as the procedure is done<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * but should wait a result request from the client (see executor.removeResult(procId))<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   * The client will call something like master.isProcDone() or master.getProcResult()<a name="line.154"></a>
+<span class="sourceLineNo">155</span>   * which will return the result/state to the client, and it will mark the completed<a name="line.155"></a>
+<span class="sourceLineNo">156</span>   * proc as ready to delete. note that the client may not receive the response from<a name="line.156"></a>
+<span class="sourceLineNo">157</span>   * the master (e.g. master failover) so, if we delay a bit the real deletion of<a name="line.157"></a>
+<span class="sourceLineNo">158</span>   * the proc result the client will be able to get the result the next try.<a name="line.158"></a>
+<span class="sourceLineNo">159</span>   */<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  private static class CompletedProcedureCleaner&lt;TEnvironment&gt;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>      extends ProcedureInMemoryChore&lt;TEnvironment&gt; {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private static final Logger LOG = LoggerFactory.getLogger(CompletedProcedureCleaner.class);<a name="line.162"></a>
+<span class="sourceLineNo">163</span><a name="line.163"></a>
+<span class="sourceLineNo">164</span>    private static final String CLEANER_INTERVAL_CONF_KEY = "hbase.procedure.cleaner.interval";<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    private static final int DEFAULT_CLEANER_INTERVAL = 30 * 1000; // 30sec<a name="line.165"></a>
+<span class="sourceLineNo">166</span><a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private static final String EVICT_TTL_CONF_KEY = "hbase.procedure.cleaner.evict.ttl";<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    private static final int DEFAULT_EVICT_TTL = 15 * 60000; // 15min<a name="line.168"></a>
+<span class="sourceLineNo">169</span><a name="line.169"></a>
+<span class="sourceLineNo">170</span>    private static final String EVICT_ACKED_TTL_CONF_KEY ="hbase.procedure.cleaner.acked.evict.ttl";<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    private static final int DEFAULT_ACKED_EVICT_TTL = 5 * 60000; // 5min<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    private static final int DEFAULT_BATCH_SIZE = 32;<a name="line.174"></a>
+<span class="sourceLineNo">175</span><a name="line.175"></a>
+<span class="sourceLineNo">176</span>    private final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed;<a name="line.176"></a>
+<span class="sourceLineNo">177</span>    private final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap;<a name="line.177"></a>
+<span class="sourceLineNo">178</span>    private final ProcedureStore store;<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    private Configuration conf;<a name="line.179"></a>
+<span class="sourceLineNo">180</span><a name="line.180"></a>
+<span class="sourceLineNo">181</span>    public CompletedProcedureCleaner(Configuration conf, final ProcedureStore store,<a name="line.181"></a>
+<span class="sourceLineNo">182</span>        final Map&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completedMap,<a name="line.182"></a>
+<span class="sourceLineNo">183</span>        final Map&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap) {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      // set the timeout interval that triggers the periodic-procedure<a name="line.184"></a>
+<span class="sourceLineNo">185</span>      super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));<a name="line.185"></a>
+<span class="sourceLineNo">186</span>      this.completed = completedMap;<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      this.nonceKeysToProcIdsMap = nonceKeysToProcIdsMap;<a name="line.187"></a>
+<span class="sourceLineNo">188</span>      this.store = store;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      this.conf = conf;<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
+<span class="sourceLineNo">191</span><a name="line.191"></a>
+<span class="sourceLineNo">192</span>    @Override<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    protected void periodicExecute(final TEnvironment env) {<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      if (completed.isEmpty()) {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        if (LOG.isTraceEnabled()) {<a name="line.195"></a>
+<span class="sourceLineNo">196</span>          LOG.trace("No completed procedures to cleanup.");<a name="line.196"></a>
+<span class="sourceLineNo">197</span>        }<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        return;<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      }<a name="line.199"></a>
+<span class="sourceLineNo">200</span><a name="line.200"></a>
+<span class="sourceLineNo">201</span>      final long evictTtl = conf.getInt(EVICT_TTL_CONF_KEY, DEFAULT_EVICT_TTL);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>      final long evictAckTtl = conf.getInt(EVICT_ACKED_TTL_CONF_KEY, DEFAULT_ACKED_EVICT_TTL);<a name="line.202"></a>
+<span class="sourceLineNo">203</span>      final int batchSize = conf.getInt(BATCH_SIZE_CONF_KEY, DEFAULT_BATCH_SIZE);<a name="line.203"></a>
+<span class="sourceLineNo">204</span><a name="line.204"></a>
+<span class="sourceLineNo">205</span>      final long[] batchIds = new long[batchSize];<a name="line.205"></a>
+<span class="sourceLineNo">206</span>      int batchCount = 0;<a name="line.206"></a>
+<span class="sourceLineNo">207</span><a name="line.207"></a>
+<span class="sourceLineNo">208</span>      final long now = EnvironmentEdgeManager.currentTime();<a name="line.208"></a>
+<span class="sourceLineNo">209</span>      final Iterator&lt;Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt;&gt; it =<a name="line.209"></a>
+<span class="sourceLineNo">210</span>        completed.entrySet().iterator();<a name="line.210"></a>
+<span class="sourceLineNo">211</span>      while (it.hasNext() &amp;&amp; store.isRunning()) {<a name="line.211"></a>
+<span class="sourceLineNo">212</span>        final Map.Entry&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; entry = it.next();<a name="line.212"></a>
+<span class="sourceLineNo">213</span>        final CompletedProcedureRetainer&lt;TEnvironment&gt; retainer = entry.getValue();<a name="line.213"></a>
+<span class="sourceLineNo">214</span>        final Procedure&lt;?&gt; proc = retainer.getProcedure();<a name="line.214"></a>
+<span class="sourceLineNo">215</span><a name="line.215"></a>
+<span class="sourceLineNo">216</span>        // TODO: Select TTL based on Procedure type<a name="line.216"></a>
+<span class="sourceLineNo">217</span>        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>          // Failed procedures aren't persisted in WAL.<a name="line.218"></a>
+<span class="sourceLineNo">219</span>          if (!(proc instanceof FailedProcedure)) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>            batchIds[batchCount++] = entry.getKey();<a name="line.220"></a>
+<span class="sourceLineNo">221</span>            if (batchCount == batchIds.length) {<a name="line.221"></a>
+<span class="sourceLineNo">222</span>              store.delete(batchIds, 0, batchCount);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>              batchCount = 0;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>            }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>          }<a name="line.225"></a>
+<span class="sourceLineNo">226</span>          final NonceKey nonceKey = proc.getNonceKey();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>          if (nonceKey != null) {<a name="line.227"></a>
+<span class="sourceLineNo">228</span>            nonceKeysToProcIdsMap.remove(nonceKey);<a name="line.228"></a>
+<span class="sourceLineNo">229</span>          }<a name="line.229"></a>
+<span class="sourceLineNo">230</span>          it.remove();<a name="line.230"></a>
+<span class="sourceLineNo">231</span>          LOG.trace("Evict completed {}", proc);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>        }<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      }<a name="line.233"></a>
+<span class="sourceLineNo">234</span>      if (batchCount &gt; 0) {<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        store.delete(batchIds, 0, batchCount);<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><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   * Once a Root-Procedure completes (success or failure), the result will be added to this map.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>   * The user of ProcedureExecutor should call getResult(procId) to get the result.<a name="line.243"></a>
+<span class="sourceLineNo">244</span>   */<a name="line.244"></a>
+<span class="sourceLineNo">245</span>  private final ConcurrentHashMap&lt;Long, CompletedProcedureRetainer&lt;TEnvironment&gt;&gt; completed =<a name="line.245"></a>
+<span class="sourceLineNo">246</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.<a name="line.249"></a>
+<span class="sourceLineNo">250</span>   * The RootProcedureState contains the execution stack of the Root-Procedure,<a name="line.250"></a>
+<span class="sourceLineNo">251</span>   * It is added to the map by submitProcedure() and removed on procedure completion.<a name="line.251"></a>
+<span class="sourceLineNo">252</span>   */<a name="line.252"></a>
+<span class="sourceLineNo">253</span>  private final ConcurrentHashMap&lt;Long, RootProcedureState&lt;TEnvironment&gt;&gt; rollbackStack =<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    new ConcurrentHashMap&lt;&gt;();<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>   * Helper map to lookup the live procedures by ID.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>   * This map contains every procedure. root-procedures and subprocedures.<a name="line.258"></a>
+<span class="sourceLineNo">259</span>   */<a name="line.259"></a>
+<span class="sourceLineNo">260</span>  private final ConcurrentHashMap&lt;Long, Procedure&lt;TEnvironment&gt;&gt; procedures =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>    new ConcurrentHashMap&lt;&gt;();<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  /**<a name="line.263"></a>
+<span class="sourceLineNo">264</span>   * Helper map to lookup whether the procedure already issued from the same client. This map<a name="line.264"></a>
+<span class="sourceLineNo">265</span>   * contains every root procedure.<a name="line.265"></a>
+<span class="sourceLineNo">266</span>   */<a name="line.266"></a>
+<span class="sourceLineNo">267</span>  private final ConcurrentHashMap&lt;NonceKey, Long&gt; nonceKeysToProcIdsMap = new ConcurrentHashMap&lt;&gt;();<a name="line.267"></a>
+<span class="sourceLineNo">268</span><a name="line.268"></a>
+<span class="sourceLineNo">269</span>  private final CopyOnWriteArrayList&lt;ProcedureExecutorListener&gt; listeners =<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    new CopyOnWriteArrayList&lt;&gt;();<a name="line.270"></a>
+<span class="sourceLineNo">271</span><a name="line.271"></a>
+<span class="sourceLineNo">272</span>  private Configuration conf;<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>   * Created in the {@link #start(int, boolean)} method. Destroyed in {@link #join()} (FIX! Doing<a name="line.275"></a>
+<span class="sourceLineNo">276</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.276"></a>
+<span class="sourceLineNo">277</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.277"></a>
+<span class="sourceLineNo">278</span>   * (Should be ok).<a name="line.278"></a>
+<span class="sourceLineNo">279</span>   */<a name="line.279"></a>
+<span class="sourceLineNo">280</span>  private ThreadGroup threadGroup;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.283"></a>
+<span class="sourceLineNo">284</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.284"></a>
+<span class="sourceLineNo">285</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.285"></a>
+<span class="sourceLineNo">286</span>   * (Should be ok).<a name="line.286"></a>
+<span class="sourceLineNo">287</span>   */<a name="line.287"></a>
+<span class="sourceLineNo">288</span>  private CopyOnWriteArrayList&lt;WorkerThread&gt; workerThreads;<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>   * Created in the {@link #start(int, boolean)} method. Terminated in {@link #join()} (FIX! Doing<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * resource handling rather than observing in a #join is unexpected).<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   * Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery<a name="line.293"></a>
+<span class="sourceLineNo">294</span>   * (Should be ok).<a name="line.294"></a>
+<span class="sourceLineNo">295</span>   */<a name="line.295"></a>
+<span class="sourceLineNo">296</span>  private TimeoutExecutorThread&lt;TEnvironment&gt; timeoutExecutor;<a name="line.296"></a>
+<span class="sourceLineNo">297</span><a name="line.297"></a>
+<span class="sourceLineNo">298</span>  private int corePoolSize;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>  private int maxPoolSize;<a name="line.299"></a>
+<span class="sourceLineNo">300</span><a name="line.300"></a>
+<span class="sourceLineNo">301</span>  private volatile long keepAliveTime;<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>   * Scheduler/Queue that contains runnable procedures.<a name="line.304"></a>
+<span class="sourceLineNo">305</span>   */<a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private final ProcedureScheduler scheduler;<a name="line.306"></a>
+<span class="sourceLineNo">307</span><a name="line.307"></a>
+<span class="sourceLineNo">308</span>  private final AtomicLong lastProcId = new AtomicLong(-1);<a name="line.308"></a>
+<span class="sourceLineNo">309</span>  private final AtomicLong workerId = new AtomicLong(0);<a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private final AtomicInteger activeExecutorCount = new AtomicInteger(0);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>  private final AtomicBoolean running = new AtomicBoolean(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  private final TEnvironment environment;<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private final ProcedureStore store;<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>  private final boolean checkOwnerSet;<a name="line.315"></a>
+<span class="sourceLineNo">316</span><a name="line.316"></a>
+<span class="sourceLineNo">317</span>  // To prevent concurrent execution of the same procedure.<a name="line.317"></a>
+<span class="sourceLineNo">318</span>  // For some rare cases, especially if the procedure uses ProcedureEvent, it is possible that the<a name="line.318"></a>
+<span class="sourceLineNo">319</span>  // procedure is woken up before we finish the suspend which causes the same procedures to be<a name="line.319"></a>
+<span class="sourceLineNo">320</span>  // executed in parallel. This does lead to some problems, see HBASE-20939&amp;HBASE-20949, and is also<a name="line.320"></a>
+<span class="sourceLineNo">321</span>  // a bit confusing to the developers. So here we introduce this lock to prevent the concurrent<a name="line.321"></a>
+<span class="sourceLineNo">322</span>  // execution of the same procedure.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>  private final IdLock procExecutionLock = new IdLock();<a name="line.323"></a>
+<span class="sourceLineNo">324</span><a name="line.324"></a>
+<span class="sourceLineNo">325</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.325"></a>
+<span class="sourceLineNo">326</span>      final ProcedureStore store) {<a name="line.326"></a>
+<span class="sourceLineNo">327</span>    this(conf, environment, store, new SimpleProcedureScheduler());<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>  }<a name="line.330"></a>
-<span class="sourceLineNo">331</span><a name="line.331"></a>
-<span class="sourceLineNo">332</span>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.336"></a>
-<span class="sourceLineNo">337</span><a name="line.337"></a>
-<span class="sourceLineNo">338</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>      @Override<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      public void setMaxProcId(long maxProcId) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        lastProcId.set(maxProcId);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>      }<a name="line.343"></a>
-<span class="sourceLineNo">344</span><a name="line.344"></a>
-<span class="sourceLineNo">345</span>      @Override<a name="line.345"></a>
-<span class="sourceLineNo">346</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.346"></a>
-<span class="sourceLineNo">347</span>        loadProcedures(procIter, abortOnCorruption);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>      }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>      @Override<a name="line.350"></a>
-<span class="sourceLineNo">351</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>        int corruptedCount = 0;<a name="line.352"></a>
-<span class="sourceLineNo">353</span>        while (procIter.hasNext()) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          LOG.error("Corrupt " + proc);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          corruptedCount++;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        }<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>  }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    proc.restoreLock(getEnvironment());<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    restored.add(proc.getProcId());<a name="line.367"></a>
-<span class="sourceLineNo">368</span>  }<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.370"></a>
-<span class="sourceLineNo">371</span>    while (!stack.isEmpty()) {<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      restoreLock(stack.pop(), restored);<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  // Restore the locks for all the procedures.<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  // calling the acquireLock method for the parent procedure.<a name="line.379"></a>
-<span class="sourceLineNo">380</span>  // The algorithm is straight-forward:<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.382"></a>
-<span class="sourceLineNo">383</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  // unless<a name="line.384"></a>
-<span class="sourceLineNo">385</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.387"></a>
-<span class="sourceLineNo">388</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  private void restoreLocks() {<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.390"></a>
-<span class="sourceLineNo">391</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    procedures.values().forEach(proc -&gt; {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      for (;;) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>        if (restored.contains(proc.getProcId())) {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>          restoreLocks(stack, restored);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>          return;<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        if (!proc.hasParent()) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          restoreLock(proc, restored);<a name="line.399"></a>
-<span class="sourceLineNo">400</span>          restoreLocks(stack, restored);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>          return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>        }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>        stack.push(proc);<a name="line.403"></a>
-<span class="sourceLineNo">404</span>        proc = procedures.get(proc.getParentProcId());<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      }<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    });<a name="line.406"></a>
-<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
-<span class="sourceLineNo">408</span><a name="line.408"></a>
-<span class="sourceLineNo">409</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      throws IOException {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    // 1. Build the rollback stack<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    int runnablesCount = 0;<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    int failedCount = 0;<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    while (procIter.hasNext()) {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      boolean finished = procIter.isNextFinished();<a name="line.415"></a>
-<span class="sourceLineNo">416</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.417"></a>
-<span class="sourceLineNo">418</span>      long procId = proc.getProcId();<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>      if (finished) {<a name="line.420"></a>
-<span class="sourceLineNo">421</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        LOG.debug("Completed {}", proc);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      } else {<a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (!proc.hasParent()) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<a name="line.426"></a>
-<span class="sourceLineNo">427</span>        }<a name="line.427"></a>
+<span class="sourceLineNo">330</span>  public ProcedureExecutor(final Configuration conf, final TEnvironment environment,<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      final ProcedureStore store, final ProcedureScheduler scheduler) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>    this.environment = environment;<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    this.scheduler = scheduler;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    this.store = store;<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    this.conf = conf;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    this.checkOwnerSet = conf.getBoolean(CHECK_OWNER_SET_CONF_KEY, DEFAULT_CHECK_OWNER_SET);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    refreshConfiguration(conf);<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>  private void load(final boolean abortOnCorruption) throws IOException {<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    Preconditions.checkArgument(completed.isEmpty(), "completed not empty");<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    Preconditions.checkArgument(rollbackStack.isEmpty(), "rollback state not empty");<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    Preconditions.checkArgument(procedures.isEmpty(), "procedure map not empty");<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    Preconditions.checkArgument(scheduler.size() == 0, "run queue not empty");<a name="line.345"></a>
+<span class="sourceLineNo">346</span><a name="line.346"></a>
+<span class="sourceLineNo">347</span>    store.load(new ProcedureStore.ProcedureLoader() {<a name="line.347"></a>
+<span class="sourceLineNo">348</span>      @Override<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      public void setMaxProcId(long maxProcId) {<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        assert lastProcId.get() &lt; 0 : "expected only one call to setMaxProcId()";<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        lastProcId.set(maxProcId);<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>      @Override<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      public void load(ProcedureIterator procIter) throws IOException {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        loadProcedures(procIter, abortOnCorruption);<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>      @Override<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      public void handleCorrupted(ProcedureIterator procIter) throws IOException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        int corruptedCount = 0;<a name="line.361"></a>
+<span class="sourceLineNo">362</span>        while (procIter.hasNext()) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          Procedure&lt;?&gt; proc = procIter.next();<a name="line.363"></a>
+<span class="sourceLineNo">364</span>          LOG.error("Corrupt " + proc);<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          corruptedCount++;<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        }<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        if (abortOnCorruption &amp;&amp; corruptedCount &gt; 0) {<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          throw new IOException("found " + corruptedCount + " corrupted procedure(s) on replay");<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>    });<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>  private void restoreLock(Procedure&lt;TEnvironment&gt; proc, Set&lt;Long&gt; restored) {<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    proc.restoreLock(getEnvironment());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    restored.add(proc.getProcId());<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>  private void restoreLocks(Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack, Set&lt;Long&gt; restored) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>    while (!stack.isEmpty()) {<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      restoreLock(stack.pop(), restored);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  // Restore the locks for all the procedures.<a name="line.385"></a>
+<span class="sourceLineNo">386</span>  // Notice that we need to restore the locks starting from the root proc, otherwise there will be<a name="line.386"></a>
+<span class="sourceLineNo">387</span>  // problem that a sub procedure may hold the exclusive lock first and then we are stuck when<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  // calling the acquireLock method for the parent procedure.<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  // The algorithm is straight-forward:<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  // 1. Use a set to record the procedures which locks have already been restored.<a name="line.390"></a>
+<span class="sourceLineNo">391</span>  // 2. Use a stack to store the hierarchy of the procedures<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  // 3. For all the procedure, we will first try to find its parent and push it into the stack,<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  // unless<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  // a. We have no parent, i.e, we are the root procedure<a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // b. The lock has already been restored(by checking the set introduced in #1)<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  // then we start to pop the stack and call acquireLock for each procedure.<a name="line.396"></a>
+<span class="sourceLineNo">397</span>  // Notice that this should be done for all procedures, not only the ones in runnableList.<a name="line.397"></a>
+<span class="sourceLineNo">398</span>  private void restoreLocks() {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>    Set&lt;Long&gt; restored = new HashSet&lt;&gt;();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    Deque&lt;Procedure&lt;TEnvironment&gt;&gt; stack = new ArrayDeque&lt;&gt;();<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    procedures.values().forEach(proc -&gt; {<a name="line.401"></a>
+<span class="sourceLineNo">402</span>      for (;;) {<a name="line.402"></a>
+<span class="sourceLineNo">403</span>        if (restored.contains(proc.getProcId())) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>          restoreLocks(stack, restored);<a name="line.404"></a>
+<span class="sourceLineNo">405</span>          return;<a name="line.405"></a>
+<span class="sourceLineNo">406</span>        }<a name="line.406"></a>
+<span class="sourceLineNo">407</span>        if (!proc.hasParent()) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>          restoreLock(proc, restored);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>          restoreLocks(stack, restored);<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          return;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        }<a name="line.411"></a>
+<span class="sourceLineNo">412</span>        stack.push(proc);<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        proc = procedures.get(proc.getParentProcId());<a name="line.413"></a>
+<span class="sourceLineNo">414</span>      }<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    });<a name="line.415"></a>
+<span class="sourceLineNo">416</span>  }<a name="line.416"></a>
+<span class="sourceLineNo">417</span><a name="line.417"></a>
+<span class="sourceLineNo">418</span>  private void loadProcedures(ProcedureIterator procIter, boolean abortOnCorruption)<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    // 1. Build the rollback stack<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    int runnablesCount = 0;<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    int failedCount = 0;<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    while (procIter.hasNext()) {<a name="line.423"></a>
+<span class="sourceLineNo">424</span>      boolean finished = procIter.isNextFinished();<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      NonceKey nonceKey = proc.getNonceKey();<a name="line.426"></a>
+<span class="sourceLineNo">427</span>      long procId = proc.getProcId();<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>        // add the procedure to the map<a name="line.429"></a>
-<span class="sourceLineNo">430</span>        proc.beforeReplay(getEnvironment());<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        procedures.put(proc.getProcId(), proc);<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>          runnablesCount++;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.435"></a>
-<span class="sourceLineNo">436</span>          failedCount++;<a name="line.436"></a>
-<span class="sourceLineNo">437</span>        }<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>      // add the nonce to the map<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      if (nonceKey != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>    }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>    // 2. Initialize the stacks<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.447"></a>
-<span class="sourceLineNo">448</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // introduce the restore lock stage.<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.452"></a>
-<span class="sourceLineNo">453</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.456"></a>
-<span class="sourceLineNo">457</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.457"></a>
-<span class="sourceLineNo">458</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    procIter.reset();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    while (procIter.hasNext()) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>      if (procIter.isNextFinished()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        procIter.skipNext();<a name="line.463"></a>
-<span class="sourceLineNo">464</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>      LOG.debug("Loading {}", proc);<a name="line.470"></a>
-<span class="sourceLineNo">471</span><a name="line.471"></a>
-<span class="sourceLineNo">472</span>      Long rootProcId = getRootProcedureId(proc);<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      if (rootProcId == null) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>        // The 'proc' was ready to run but the root procedure was rolledback?<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        scheduler.addBack(proc);<a name="line.475"></a>
-<span class="sourceLineNo">476</span>        continue;<a name="line.476"></a>
-<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">429</span>      if (finished) {<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        completed.put(proc.getProcId(), new CompletedProcedureRetainer&lt;&gt;(proc));<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        LOG.debug("Completed {}", proc);<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      } else {<a name="line.432"></a>
+<span class="sourceLineNo">433</span>        if (!proc.hasParent()) {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>          assert !proc.isFinished() : "unexpected finished procedure";<a name="line.434"></a>
+<span class="sourceLineNo">435</span>          rollbackStack.put(proc.getProcId(), new RootProcedureState&lt;&gt;());<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>        // add the procedure to the map<a name="line.438"></a>
+<span class="sourceLineNo">439</span>        proc.beforeReplay(getEnvironment());<a name="line.439"></a>
+<span class="sourceLineNo">440</span>        procedures.put(proc.getProcId(), proc);<a name="line.440"></a>
+<span class="sourceLineNo">441</span><a name="line.441"></a>
+<span class="sourceLineNo">442</span>        if (proc.getState() == ProcedureState.RUNNABLE) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          runnablesCount++;<a name="line.443"></a>
+<span class="sourceLineNo">444</span>        } else if (proc.getState() == ProcedureState.FAILED) {<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          failedCount++;<a name="line.445"></a>
+<span class="sourceLineNo">446</span>        }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>      }<a name="line.447"></a>
+<span class="sourceLineNo">448</span><a name="line.448"></a>
+<span class="sourceLineNo">449</span>      // add the nonce to the map<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      if (nonceKey != null) {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        nonceKeysToProcIdsMap.put(nonceKey, procId);<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>    // 2. Initialize the stacks<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    // In the old implementation, for procedures in FAILED state, we will push it into the<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    // ProcedureScheduler directly to execute the rollback. But this does not work after we<a name="line.457"></a>
+<span class="sourceLineNo">458</span>    // introduce the restore lock stage.<a name="line.458"></a>
+<span class="sourceLineNo">459</span>    // For now, when we acquire a xlock, we will remove the queue from runQueue in scheduler, and<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    // then when a procedure which has lock access, for example, a sub procedure of the procedure<a name="line.460"></a>
+<span class="sourceLineNo">461</span>    // which has the xlock, is pushed into the scheduler, we will add the queue back to let the<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    // workers poll from it. The assumption here is that, the procedure which has the xlock should<a name="line.462"></a>
+<span class="sourceLineNo">463</span>    // have been polled out already, so when loading we can not add the procedure to scheduler first<a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // and then call acquireLock, since the procedure is still in the queue, and since we will<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    // remove the queue from runQueue, then no one can poll it out, then there is a dead lock<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; runnableList = new ArrayList&lt;&gt;(runnablesCount);<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    List&lt;Procedure&lt;TEnvironment&gt;&gt; failedList = new ArrayList&lt;&gt;(failedCount);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>    Set&lt;Procedure&lt;TEnvironment&gt;&gt; waitingSet = null;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>    procIter.reset();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    while (procIter.hasNext()) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>      if (procIter.isNextFinished()) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        procIter.skipNext();<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        continue;<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>      Procedure&lt;TEnvironment&gt; proc = procIter.next();<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      assert !(proc.isFinished() &amp;&amp; !proc.hasParent()) : "unexpected completed proc=" + proc;<a name="line.477"></a>
 <span class="sourceLineNo">478</span><a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (proc.hasParent()) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        Procedure&lt;TEnvironment&gt; parent = procedures.get(proc.getParentProcId());<a name="line.480"></a>
-<span class="sourceLineNo">481</span>        // corrupted procedures are handled later at step 3<a name="line.481"></a>
-<span class="sourceLineNo">482</span>        if (parent != null &amp;&amp; !proc.isFinished()) {<a name="line

<TRUNCATED>

[23/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
----------------------------------------------------------------------
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
index e0d5c9f..44d141d 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-public class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.75">ProcedureExecutor</a>&lt;TEnvironment&gt;
+public class <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.76">ProcedureExecutor</a>&lt;TEnvironment&gt;
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 <div class="block">Thread Pool that executes the submitted procedures.
  The executor has a ProcedureStore associated.
@@ -261,50 +261,54 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </td>
 </tr>
 <tr class="altColor">
+<td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/util/IdLock.html" title="class in org.apache.hadoop.hbase.util">IdLock</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#procExecutionLock">procExecutionLock</a></span></code>&nbsp;</td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.html" title="class in org.apache.hadoop.hbase.procedure2">RootProcedureState</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#rollbackStack">rollbackStack</a></span></code>
 <div class="block">Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.</div>
 </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/atomic/AtomicBoolean.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicBoolean</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#running">running</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#scheduler">scheduler</a></span></code>
 <div class="block">Scheduler/Queue that contains runnable procedures.</div>
 </td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#store">store</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>(package private) <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.Testing</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#testing">testing</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#threadGroup">threadGroup</a></span></code>
 <div class="block">Created in the <code>#start(int, boolean)</code> method.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private <a href="../../../../../org/apache/hadoop/hbase/procedure2/TimeoutExecutorThread.html" title="class in org.apache.hadoop.hbase.procedure2">TimeoutExecutorThread</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#timeoutExecutor">timeoutExecutor</a></span></code>
 <div class="block">Created in the <code>#start(int, boolean)</code> method.</div>
 </td>
 </tr>
-<tr class="rowColor">
+<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"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#WORKER_KEEP_ALIVE_TIME_CONF_KEY">WORKER_KEEP_ALIVE_TIME_CONF_KEY</a></span></code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private <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/procedure2/ProcedureExecutor.html#workerId">workerId</a></span></code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html?is-external=true" title="class or interface in java.util.concurrent">CopyOnWriteArrayList</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.WorkerThread</a>&gt;</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#workerThreads">workerThreads</a></span></code>
 <div class="block">Created in the <code>#start(int, boolean)</code> method.</div>
@@ -706,7 +710,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.76">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.77">LOG</a></pre>
 </li>
 </ul>
 <a name="CHECK_OWNER_SET_CONF_KEY">
@@ -715,7 +719,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>CHECK_OWNER_SET_CONF_KEY</h4>
-<pre>public 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/procedure2/ProcedureExecutor.html#line.78">CHECK_OWNER_SET_CONF_KEY</a></pre>
+<pre>public 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/procedure2/ProcedureExecutor.html#line.79">CHECK_OWNER_SET_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.CHECK_OWNER_SET_CONF_KEY">Constant Field Values</a></dd>
@@ -728,7 +732,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_CHECK_OWNER_SET</h4>
-<pre>private static final&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.79">DEFAULT_CHECK_OWNER_SET</a></pre>
+<pre>private static final&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.80">DEFAULT_CHECK_OWNER_SET</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.DEFAULT_CHECK_OWNER_SET">Constant Field Values</a></dd>
@@ -741,7 +745,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>WORKER_KEEP_ALIVE_TIME_CONF_KEY</h4>
-<pre>public 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/procedure2/ProcedureExecutor.html#line.81">WORKER_KEEP_ALIVE_TIME_CONF_KEY</a></pre>
+<pre>public 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/procedure2/ProcedureExecutor.html#line.82">WORKER_KEEP_ALIVE_TIME_CONF_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.procedure2.ProcedureExecutor.WORKER_KEEP_ALIVE_TIME_CONF_KEY">Constant Field Values</a></dd>
@@ -754,7 +758,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_WORKER_KEEP_ALIVE_TIME</h4>
-<pre>private static final&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.83">DEFAULT_WORKER_KEEP_ALIVE_TIME</a></pre>
+<pre>private static final&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.84">DEFAULT_WORKER_KEEP_ALIVE_TIME</a></pre>
 </li>
 </ul>
 <a name="testing">
@@ -763,7 +767,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testing</h4>
-<pre><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.Testing</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.85">testing</a></pre>
+<pre><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.Testing.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.Testing</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.86">testing</a></pre>
 </li>
 </ul>
 <a name="completed">
@@ -772,7 +776,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>completed</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.244">completed</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.CompletedProcedureRetainer.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.CompletedProcedureRetainer</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.245">completed</a></pre>
 <div class="block">Map the the procId returned by submitProcedure(), the Root-ProcID, to the Procedure.
  Once a Root-Procedure completes (success or failure), the result will be added to this map.
  The user of ProcedureExecutor should call getResult(procId) to get the result.</div>
@@ -784,7 +788,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>rollbackStack</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.html" title="class in org.apache.hadoop.hbase.procedure2">RootProcedureState</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.252">rollbackStack</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.html" title="class in org.apache.hadoop.hbase.procedure2">RootProcedureState</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.253">rollbackStack</a></pre>
 <div class="block">Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.
  The RootProcedureState contains the execution stack of the Root-Procedure,
  It is added to the map by submitProcedure() and removed on procedure completion.</div>
@@ -796,7 +800,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>procedures</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.259">procedures</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>,<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.260">procedures</a></pre>
 <div class="block">Helper map to lookup the live procedures by ID.
  This map contains every procedure. root-procedures and subprocedures.</div>
 </li>
@@ -807,7 +811,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>nonceKeysToProcIdsMap</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.266">nonceKeysToProcIdsMap</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentHashMap</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.267">nonceKeysToProcIdsMap</a></pre>
 <div class="block">Helper map to lookup whether the procedure already issued from the same client. This map
  contains every root procedure.</div>
 </li>
@@ -818,7 +822,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>listeners</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html?is-external=true" title="class or interface in java.util.concurrent">CopyOnWriteArrayList</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.268">listeners</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html?is-external=true" title="class or interface in java.util.concurrent">CopyOnWriteArrayList</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.269">listeners</a></pre>
 </li>
 </ul>
 <a name="conf">
@@ -827,7 +831,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>conf</h4>
-<pre>private&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.271">conf</a></pre>
+<pre>private&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.272">conf</a></pre>
 </li>
 </ul>
 <a name="threadGroup">
@@ -836,7 +840,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>threadGroup</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.279">threadGroup</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html?is-external=true" title="class or interface in java.lang">ThreadGroup</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.280">threadGroup</a></pre>
 <div class="block">Created in the <code>#start(int, boolean)</code> method. Destroyed in <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#join--"><code>join()</code></a> (FIX! Doing
  resource handling rather than observing in a #join is unexpected).
  Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery
@@ -849,7 +853,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>workerThreads</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html?is-external=true" title="class or interface in java.util.concurrent">CopyOnWriteArrayList</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.WorkerThread</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.287">workerThreads</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html?is-external=true" title="class or interface in java.util.concurrent">CopyOnWriteArrayList</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.WorkerThread.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.WorkerThread</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.288">workerThreads</a></pre>
 <div class="block">Created in the <code>#start(int, boolean)</code> method. Terminated in <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#join--"><code>join()</code></a> (FIX! Doing
  resource handling rather than observing in a #join is unexpected).
  Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery
@@ -862,7 +866,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>timeoutExecutor</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/TimeoutExecutorThread.html" title="class in org.apache.hadoop.hbase.procedure2">TimeoutExecutorThread</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.295">timeoutExecutor</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/TimeoutExecutorThread.html" title="class in org.apache.hadoop.hbase.procedure2">TimeoutExecutorThread</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt; <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.296">timeoutExecutor</a></pre>
 <div class="block">Created in the <code>#start(int, boolean)</code> method. Terminated in <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#join--"><code>join()</code></a> (FIX! Doing
  resource handling rather than observing in a #join is unexpected).
  Overridden when we do the ProcedureTestingUtility.testRecoveryAndDoubleExecution trickery
@@ -875,7 +879,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>corePoolSize</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.297">corePoolSize</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.298">corePoolSize</a></pre>
 </li>
 </ul>
 <a name="maxPoolSize">
@@ -884,7 +888,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>maxPoolSize</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.298">maxPoolSize</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.299">maxPoolSize</a></pre>
 </li>
 </ul>
 <a name="keepAliveTime">
@@ -893,7 +897,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>keepAliveTime</h4>
-<pre>private volatile&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.300">keepAliveTime</a></pre>
+<pre>private volatile&nbsp;long <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.301">keepAliveTime</a></pre>
 </li>
 </ul>
 <a name="scheduler">
@@ -902,7 +906,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>scheduler</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.305">scheduler</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.306">scheduler</a></pre>
 <div class="block">Scheduler/Queue that contains runnable procedures.</div>
 </li>
 </ul>
@@ -912,7 +916,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>lastProcId</h4>
-<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.307">lastProcId</a></pre>
+<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.308">lastProcId</a></pre>
 </li>
 </ul>
 <a name="workerId">
@@ -921,7 +925,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>workerId</h4>
-<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.308">workerId</a></pre>
+<pre>private final&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> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.309">workerId</a></pre>
 </li>
 </ul>
 <a name="activeExecutorCount">
@@ -930,7 +934,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>activeExecutorCount</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.309">activeExecutorCount</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.310">activeExecutorCount</a></pre>
 </li>
 </ul>
 <a name="running">
@@ -939,7 +943,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>running</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicBoolean.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicBoolean</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.310">running</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicBoolean.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicBoolean</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.311">running</a></pre>
 </li>
 </ul>
 <a name="environment">
@@ -948,7 +952,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>environment</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.311">environment</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.312">environment</a></pre>
 </li>
 </ul>
 <a name="store">
@@ -957,16 +961,25 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>store</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.312">store</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.313">store</a></pre>
 </li>
 </ul>
 <a name="checkOwnerSet">
 <!--   -->
 </a>
-<ul class="blockListLast">
+<ul class="blockList">
 <li class="blockList">
 <h4>checkOwnerSet</h4>
-<pre>private final&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.314">checkOwnerSet</a></pre>
+<pre>private final&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.315">checkOwnerSet</a></pre>
+</li>
+</ul>
+<a name="procExecutionLock">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>procExecutionLock</h4>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/IdLock.html" title="class in org.apache.hadoop.hbase.util">IdLock</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.323">procExecutionLock</a></pre>
 </li>
 </ul>
 </li>
@@ -985,7 +998,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>ProcedureExecutor</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.316">ProcedureExecutor</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.325">ProcedureExecutor</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                          <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&nbsp;environment,
                          <a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a>&nbsp;store)</pre>
 </li>
@@ -998,7 +1011,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>ProcedureExecutor</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.321">ProcedureExecutor</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.330">ProcedureExecutor</a>(org.apache.hadoop.conf.Configuration&nbsp;conf,
                          <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&nbsp;environment,
                          <a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a>&nbsp;store,
                          <a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a>&nbsp;scheduler)</pre>
@@ -1018,7 +1031,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>load</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.332">load</a>(boolean&nbsp;abortOnCorruption)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.341">load</a>(boolean&nbsp;abortOnCorruption)
            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>
@@ -1032,7 +1045,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>restoreLock</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.365">restoreLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.374">restoreLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
                          <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/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;restored)</pre>
 </li>
 </ul>
@@ -1042,7 +1055,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>restoreLocks</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.370">restoreLocks</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/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;stack,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.379">restoreLocks</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/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;stack,
                           <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/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;restored)</pre>
 </li>
 </ul>
@@ -1052,7 +1065,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>restoreLocks</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.389">restoreLocks</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.398">restoreLocks</a>()</pre>
 </li>
 </ul>
 <a name="loadProcedures-org.apache.hadoop.hbase.procedure2.store.ProcedureStore.ProcedureIterator-boolean-">
@@ -1061,7 +1074,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>loadProcedures</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.409">loadProcedures</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.ProcedureIterator.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore.ProcedureIterator</a>&nbsp;procIter,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.418">loadProcedures</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.ProcedureIterator.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore.ProcedureIterator</a>&nbsp;procIter,
                             boolean&nbsp;abortOnCorruption)
                      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>
@@ -1076,7 +1089,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>init</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.572">init</a>(int&nbsp;numThreads,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.581">init</a>(int&nbsp;numThreads,
                  boolean&nbsp;abortOnCorruption)
           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">Initialize the procedure executor, but do not start workers. We will start them later.
@@ -1100,7 +1113,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>startWorkers</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.617">startWorkers</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.626">startWorkers</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>
 <div class="block">Start the workers.</div>
 <dl>
@@ -1115,7 +1128,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>stop</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.636">stop</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.645">stop</a>()</pre>
 </li>
 </ul>
 <a name="join--">
@@ -1124,7 +1137,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>join</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.647">join</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.656">join</a>()</pre>
 </li>
 </ul>
 <a name="refreshConfiguration-org.apache.hadoop.conf.Configuration-">
@@ -1133,7 +1146,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>refreshConfiguration</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.678">refreshConfiguration</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.687">refreshConfiguration</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 <a name="isRunning--">
@@ -1142,7 +1155,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRunning</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.687">isRunning</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.696">isRunning</a>()</pre>
 </li>
 </ul>
 <a name="getWorkerThreadCount--">
@@ -1151,7 +1164,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getWorkerThreadCount</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.694">getWorkerThreadCount</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.703">getWorkerThreadCount</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the current number of worker threads.</dd>
@@ -1164,7 +1177,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getCorePoolSize</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.701">getCorePoolSize</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.710">getCorePoolSize</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the core pool size settings.</dd>
@@ -1177,7 +1190,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getActiveExecutorCount</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.705">getActiveExecutorCount</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.714">getActiveExecutorCount</a>()</pre>
 </li>
 </ul>
 <a name="getEnvironment--">
@@ -1186,7 +1199,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getEnvironment</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.709">getEnvironment</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.718">getEnvironment</a>()</pre>
 </li>
 </ul>
 <a name="getStore--">
@@ -1195,7 +1208,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getStore</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.713">getStore</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/store/ProcedureStore.html" title="interface in org.apache.hadoop.hbase.procedure2.store">ProcedureStore</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.722">getStore</a>()</pre>
 </li>
 </ul>
 <a name="getScheduler--">
@@ -1204,7 +1217,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getScheduler</h4>
-<pre><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.717">getScheduler</a>()</pre>
+<pre><a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureScheduler.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureScheduler</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.726">getScheduler</a>()</pre>
 </li>
 </ul>
 <a name="setKeepAliveTime-long-java.util.concurrent.TimeUnit-">
@@ -1213,7 +1226,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setKeepAliveTime</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.721">setKeepAliveTime</a>(long&nbsp;keepAliveTime,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.730">setKeepAliveTime</a>(long&nbsp;keepAliveTime,
                              <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeUnit.html?is-external=true" title="class or interface in java.util.concurrent">TimeUnit</a>&nbsp;timeUnit)</pre>
 </li>
 </ul>
@@ -1223,7 +1236,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getKeepAliveTime</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.726">getKeepAliveTime</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeUnit.html?is-external=true" title="class or interface in java.util.concurrent">TimeUnit</a>&nbsp;timeUnit)</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.735">getKeepAliveTime</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeUnit.html?is-external=true" title="class or interface in java.util.concurrent">TimeUnit</a>&nbsp;timeUnit)</pre>
 </li>
 </ul>
 <a name="addChore-org.apache.hadoop.hbase.procedure2.ProcedureInMemoryChore-">
@@ -1232,7 +1245,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addChore</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.738">addChore</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;chore)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.747">addChore</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;chore)</pre>
 <div class="block">Add a chore procedure to the executor</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1246,7 +1259,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeChore</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.748">removeChore</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;chore)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.757">removeChore</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;chore)</pre>
 <div class="block">Remove a chore procedure from the executor</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1262,7 +1275,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>createNonceKey</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.762">createNonceKey</a>(long&nbsp;nonceGroup,
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.771">createNonceKey</a>(long&nbsp;nonceGroup,
                                long&nbsp;nonce)</pre>
 <div class="block">Create a NoneKey from the specified nonceGroup and nonce.</div>
 <dl>
@@ -1280,7 +1293,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>registerNonce</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.777">registerNonce</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey)</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.786">registerNonce</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey)</pre>
 <div class="block">Register a nonce for a procedure that is going to be submitted.
  A procId will be reserved and on submitProcedure(),
  the procedure with the specified nonce will take the reserved ProcId.
@@ -1301,7 +1314,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>unregisterNonceIfProcedureWasNotSubmitted</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.808">unregisterNonceIfProcedureWasNotSubmitted</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.817">unregisterNonceIfProcedureWasNotSubmitted</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey)</pre>
 <div class="block">Remove the NonceKey if the procedure was not submitted to the executor.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1315,7 +1328,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setFailureResultForNonce</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.882">setFailureResultForNonce</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.891">setFailureResultForNonce</a>(<a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey,
                                      <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;procName,
                                      <a href="../../../../../org/apache/hadoop/hbase/security/User.html" title="class in org.apache.hadoop.hbase.security">User</a>&nbsp;procOwner,
                                      <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;exception)</pre>
@@ -1336,7 +1349,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>submitProcedure</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.907">submitProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.916">submitProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 <div class="block">Add a new root-procedure to the executor.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1352,7 +1365,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>submitProcedure</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.919">submitProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.928">submitProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
                             <a href="../../../../../org/apache/hadoop/hbase/util/NonceKey.html" title="class in org.apache.hadoop.hbase.util">NonceKey</a>&nbsp;nonceKey)</pre>
 <div class="block">Add a new root-procedure to the executor.</div>
 <dl>
@@ -1370,7 +1383,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>submitProcedures</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.950">submitProcedures</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;[]&nbsp;procs)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.959">submitProcedures</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;[]&nbsp;procs)</pre>
 <div class="block">Add a set of new root-procedure to the executor.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1384,7 +1397,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>prepareProcedure</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.973">prepareProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.982">prepareProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="pushProcedure-org.apache.hadoop.hbase.procedure2.Procedure-">
@@ -1393,7 +1406,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pushProcedure</h4>
-<pre>private&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.982">pushProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre>private&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.991">pushProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="abort-long-">
@@ -1402,7 +1415,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>abort</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1006">abort</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1015">abort</a>(long&nbsp;procId)</pre>
 <div class="block">Send an abort notification the specified procedure.
  Depending on the procedure implementation the abort can be considered or ignored.</div>
 <dl>
@@ -1419,7 +1432,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>abort</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1017">abort</a>(long&nbsp;procId,
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1026">abort</a>(long&nbsp;procId,
                      boolean&nbsp;mayInterruptIfRunning)</pre>
 <div class="block">Send an abort notification to the specified procedure.
  Depending on the procedure implementation, the abort can be considered or ignored.</div>
@@ -1438,7 +1451,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1031">getProcedure</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1040">getProcedure</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="getProcedure-java.lang.Class-long-">
@@ -1447,7 +1460,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcedure</h4>
-<pre>public&nbsp;&lt;T extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;T&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1035">getProcedure</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a>&lt;T&gt;&nbsp;clazz,
+<pre>public&nbsp;&lt;T extends <a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;T&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1044">getProcedure</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a>&lt;T&gt;&nbsp;clazz,
                                                           long&nbsp;procId)</pre>
 </li>
 </ul>
@@ -1457,7 +1470,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getResult</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1043">getResult</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1052">getResult</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="isFinished-long-">
@@ -1466,7 +1479,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isFinished</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1059">isFinished</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1068">isFinished</a>(long&nbsp;procId)</pre>
 <div class="block">Return true if the procedure is finished.
  The state may be "completed successfully" or "failed and rolledback".
  Use getResult() to check the state or get the result data.</div>
@@ -1484,7 +1497,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isStarted</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1068">isStarted</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1077">isStarted</a>(long&nbsp;procId)</pre>
 <div class="block">Return true if the procedure is started.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1500,7 +1513,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeResult</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1080">removeResult</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1089">removeResult</a>(long&nbsp;procId)</pre>
 <div class="block">Mark the specified completed procedure, as ready to remove.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1514,7 +1527,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getResultOrProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1092">getResultOrProcedure</a>(long&nbsp;procId)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1101">getResultOrProcedure</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="isProcedureOwner-long-org.apache.hadoop.hbase.security.User-">
@@ -1523,7 +1536,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isProcedureOwner</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1108">isProcedureOwner</a>(long&nbsp;procId,
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1117">isProcedureOwner</a>(long&nbsp;procId,
                                 <a href="../../../../../org/apache/hadoop/hbase/security/User.html" title="class in org.apache.hadoop.hbase.security">User</a>&nbsp;user)</pre>
 <div class="block">Check if the user is this procedure's owner</div>
 <dl>
@@ -1542,7 +1555,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcedures</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/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1131">getProcedures</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/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1140">getProcedures</a>()</pre>
 <div class="block">Get procedures.</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1556,7 +1569,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>registerListener</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1147">registerListener</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&nbsp;listener)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1156">registerListener</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&nbsp;listener)</pre>
 </li>
 </ul>
 <a name="unregisterListener-org.apache.hadoop.hbase.procedure2.ProcedureExecutor.ProcedureExecutorListener-">
@@ -1565,7 +1578,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>unregisterListener</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1151">unregisterListener</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&nbsp;listener)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1160">unregisterListener</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.ProcedureExecutorListener.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureExecutor.ProcedureExecutorListener</a>&nbsp;listener)</pre>
 </li>
 </ul>
 <a name="sendProcedureLoadedNotification-long-">
@@ -1574,7 +1587,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sendProcedureLoadedNotification</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1155">sendProcedureLoadedNotification</a>(long&nbsp;procId)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1164">sendProcedureLoadedNotification</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="sendProcedureAddedNotification-long-">
@@ -1583,7 +1596,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sendProcedureAddedNotification</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1167">sendProcedureAddedNotification</a>(long&nbsp;procId)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1176">sendProcedureAddedNotification</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="sendProcedureFinishedNotification-long-">
@@ -1592,7 +1605,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>sendProcedureFinishedNotification</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1179">sendProcedureFinishedNotification</a>(long&nbsp;procId)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1188">sendProcedureFinishedNotification</a>(long&nbsp;procId)</pre>
 </li>
 </ul>
 <a name="nextProcId--">
@@ -1601,7 +1614,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>nextProcId</h4>
-<pre>private&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1194">nextProcId</a>()</pre>
+<pre>private&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1203">nextProcId</a>()</pre>
 </li>
 </ul>
 <a name="getLastProcId--">
@@ -1610,7 +1623,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLastProcId</h4>
-<pre>protected&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1211">getLastProcId</a>()</pre>
+<pre>protected&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1220">getLastProcId</a>()</pre>
 </li>
 </ul>
 <a name="getActiveProcIds--">
@@ -1619,7 +1632,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getActiveProcIds</h4>
-<pre>public&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;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1216">getActiveProcIds</a>()</pre>
+<pre>public&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;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1225">getActiveProcIds</a>()</pre>
 </li>
 </ul>
 <a name="getRootProcedureId-org.apache.hadoop.hbase.procedure2.Procedure-">
@@ -1628,7 +1641,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRootProcedureId</h4>
-<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1220">getRootProcedureId</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1229">getRootProcedureId</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="executeProcedure-org.apache.hadoop.hbase.procedure2.Procedure-">
@@ -1637,7 +1650,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>executeProcedure</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1227">executeProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1236">executeProcedure</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="acquireLock-org.apache.hadoop.hbase.procedure2.Procedure-">
@@ -1646,7 +1659,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>acquireLock</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2">Procedure.LockState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1319">acquireLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2">Procedure.LockState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1328">acquireLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="releaseLock-org.apache.hadoop.hbase.procedure2.Procedure-boolean-">
@@ -1655,7 +1668,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>releaseLock</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1329">releaseLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1338">releaseLock</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;proc,
                          boolean&nbsp;force)</pre>
 </li>
 </ul>
@@ -1665,7 +1678,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>executeRollback</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2">Procedure.LockState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1342">executeRollback</a>(long&nbsp;rootProcId,
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2">Procedure.LockState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1351">executeRollback</a>(long&nbsp;rootProcId,
                                             <a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.html" title="class in org.apache.hadoop.hbase.procedure2">RootProcedureState</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html" title="type parameter in ProcedureExecutor">TEnvironment</a>&gt;&nbsp;procStack)</pre>
 <div class="block">Execute the rollback of the full procedure stack. Once the procedure is rolledback, the
  root-procedure will be visible as finished to user, and the result will be the fatal exception.</div>
@@ -1677,7 +1690,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>executeRollback</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2">Procedure.LockState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.html#line.1410">executeRollback</a>(<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/procedure2/ProcedureE

<TRUNCATED>

[17/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerReportEvent.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerReportEvent.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerReportEvent.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerReportEvent.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.ServerReportEvent.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>      node = oldNode !

<TRUNCATED>

[28/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.


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

Branch: refs/heads/asf-site
Commit: 9cc58affb3190c09b2476a0ce6d5272eb1c003ea
Parents: 23357d7
Author: jenkins <bu...@apache.org>
Authored: Fri Jul 27 14:51:08 2018 +0000
Committer: jenkins <bu...@apache.org>
Committed: Fri Jul 27 14:51:08 2018 +0000

----------------------------------------------------------------------
 acid-semantics.html                             |     4 +-
 apache_hbase_reference_guide.pdf                |     4 +-
 book.html                                       |     2 +-
 bulk-loads.html                                 |     4 +-
 checkstyle-aggregate.html                       | 35870 ++++++++---------
 checkstyle.rss                                  |    20 +-
 coc.html                                        |     4 +-
 dependencies.html                               |     4 +-
 dependency-convergence.html                     |     4 +-
 dependency-info.html                            |     4 +-
 dependency-management.html                      |     4 +-
 devapidocs/constant-values.html                 |    25 +-
 devapidocs/index-all.html                       |     4 +
 .../HealthChecker.HealthCheckerExitStatus.html  |     4 +-
 .../hadoop/hbase/backup/package-tree.html       |     2 +-
 .../hadoop/hbase/client/package-tree.html       |    24 +-
 .../hadoop/hbase/filter/package-tree.html       |    10 +-
 .../hadoop/hbase/io/hfile/package-tree.html     |     8 +-
 .../hadoop/hbase/mapreduce/package-tree.html    |     4 +-
 .../RegionStates.RegionFailedOpen.html          |    22 +-
 .../hbase/master/assignment/RegionStates.html   |    86 +-
 .../hbase/master/balancer/package-tree.html     |     2 +-
 .../hadoop/hbase/master/package-tree.html       |     4 +-
 .../hbase/master/procedure/package-tree.html    |     4 +-
 .../hadoop/hbase/monitoring/package-tree.html   |     2 +-
 .../org/apache/hadoop/hbase/package-tree.html   |    16 +-
 ...edureExecutor.CompletedProcedureCleaner.html |    32 +-
 ...dureExecutor.CompletedProcedureRetainer.html |    18 +-
 .../ProcedureExecutor.FailedProcedure.html      |    20 +-
 ...ProcedureExecutor.KeepAliveWorkerThread.html |     6 +-
 ...edureExecutor.ProcedureExecutorListener.html |     8 +-
 .../procedure2/ProcedureExecutor.Testing.html   |    14 +-
 .../ProcedureExecutor.WorkerMonitor.html        |    32 +-
 .../ProcedureExecutor.WorkerThread.html         |    20 +-
 .../hbase/procedure2/ProcedureExecutor.html     |   221 +-
 .../procedure2/ProcedureSuspendedException.html |    51 +-
 .../hadoop/hbase/procedure2/package-tree.html   |     4 +-
 .../hadoop/hbase/quotas/package-tree.html       |     8 +-
 .../hadoop/hbase/regionserver/package-tree.html |    20 +-
 .../regionserver/querymatcher/package-tree.html |     2 +-
 .../hadoop/hbase/rest/model/package-tree.html   |     2 +-
 .../hbase/rsgroup/RSGroupAdminEndpoint.html     |     4 +-
 .../hbase/security/access/package-tree.html     |     2 +-
 .../hadoop/hbase/security/package-tree.html     |     4 +-
 .../hadoop/hbase/thrift/package-tree.html       |     2 +-
 .../apache/hadoop/hbase/util/IdLock.Entry.html  |    12 +-
 .../org/apache/hadoop/hbase/util/IdLock.html    |    14 +-
 .../hadoop/hbase/util/class-use/IdLock.html     |    22 +
 .../apache/hadoop/hbase/util/package-tree.html  |     8 +-
 .../apache/hadoop/hbase/util/package-use.html   |     6 +
 devapidocs/serialized-form.html                 |     4 +
 .../org/apache/hadoop/hbase/Version.html        |     6 +-
 .../RegionStates.AssignmentProcedureEvent.html  |   994 +-
 .../RegionStates.RegionFailedOpen.html          |   994 +-
 .../RegionStates.RegionStateNode.html           |   994 +-
 ...RegionStates.RegionStateStampComparator.html |   994 +-
 .../RegionStates.ServerReportEvent.html         |   994 +-
 .../assignment/RegionStates.ServerState.html    |   994 +-
 .../RegionStates.ServerStateNode.html           |   994 +-
 .../hbase/master/assignment/RegionStates.html   |   994 +-
 .../procedure/ReopenTableRegionsProcedure.html  |     2 +-
 ...edureExecutor.CompletedProcedureCleaner.html |  3700 +-
 ...dureExecutor.CompletedProcedureRetainer.html |  3700 +-
 .../ProcedureExecutor.FailedProcedure.html      |  3700 +-
 ...ProcedureExecutor.KeepAliveWorkerThread.html |  3700 +-
 ...edureExecutor.ProcedureExecutorListener.html |  3700 +-
 .../procedure2/ProcedureExecutor.Testing.html   |  3700 +-
 .../ProcedureExecutor.WorkerMonitor.html        |  3700 +-
 .../ProcedureExecutor.WorkerThread.html         |  3700 +-
 .../hbase/procedure2/ProcedureExecutor.html     |  3700 +-
 .../procedure2/ProcedureSuspendedException.html |    18 +-
 ...upAdminEndpoint.RSGroupAdminServiceImpl.html |    44 +-
 .../hbase/rsgroup/RSGroupAdminEndpoint.html     |    44 +-
 .../apache/hadoop/hbase/util/IdLock.Entry.html  |   275 +-
 .../org/apache/hadoop/hbase/util/IdLock.html    |   275 +-
 downloads.html                                  |     4 +-
 export_control.html                             |     4 +-
 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/allclasses-frame.html            |     1 +
 testdevapidocs/allclasses-noframe.html          |     1 +
 testdevapidocs/index-all.html                   |    28 +
 .../hadoop/hbase/backup/package-tree.html       |     2 +-
 .../hbase/class-use/HBaseClassTestRule.html     |    20 +-
 .../hbase/class-use/HBaseTestingUtility.html    |    18 +-
 .../TestMergeTableRegionsProcedure.html         |     4 +-
 .../assignment/TestModifyTableWhileMerging.html |   440 +
 .../assignment/TestRegionMoveAndAbandon.html    |     4 +-
 .../class-use/TestModifyTableWhileMerging.html  |   125 +
 .../hbase/master/assignment/package-frame.html  |     1 +
 .../master/assignment/package-summary.html      |    12 +-
 .../hbase/master/assignment/package-tree.html   |     1 +
 .../org/apache/hadoop/hbase/package-tree.html   |     8 +-
 .../hadoop/hbase/procedure2/package-tree.html   |     2 +-
 .../hadoop/hbase/regionserver/package-tree.html |     2 +-
 .../hbase/rsgroup/IntegrationTestRSGroup.html   |     2 +-
 .../hadoop/hbase/rsgroup/TestRSGroups.html      |     2 +-
 .../hadoop/hbase/rsgroup/TestRSGroupsBase.html  |    54 +-
 .../apache/hadoop/hbase/test/package-tree.html  |     4 +-
 .../apache/hadoop/hbase/wal/package-tree.html   |     2 +-
 testdevapidocs/overview-tree.html               |     1 +
 testdevapidocs/serialized-form.html             |     4 +
 .../assignment/TestModifyTableWhileMerging.html |   181 +
 .../hadoop/hbase/rsgroup/TestRSGroupsBase.html  |    30 +-
 122 files changed, 40329 insertions(+), 39301 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/acid-semantics.html
----------------------------------------------------------------------
diff --git a/acid-semantics.html b/acid-semantics.html
index 98ed39e..1072217 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Apache HBase (TM) ACID Properties
@@ -601,7 +601,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/apache_hbase_reference_guide.pdf
----------------------------------------------------------------------
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index a095172..7bb68be 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 1.5.0.alpha.15, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20180726142959+00'00')
-/CreationDate (D:20180726144554+00'00')
+/ModDate (D:20180727142953+00'00')
+/CreationDate (D:20180727144714+00'00')
 >>
 endobj
 2 0 obj

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/book.html
----------------------------------------------------------------------
diff --git a/book.html b/book.html
index d111c13..f2d2e4d 100644
--- a/book.html
+++ b/book.html
@@ -40950,7 +40950,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-07-26 14:29:59 UTC
+Last updated 2018-07-27 14:29:53 UTC
 </div>
 </div>
 </body>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/bulk-loads.html
----------------------------------------------------------------------
diff --git a/bulk-loads.html b/bulk-loads.html
index 71a10c6..f644ebd 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Bulk Loads in Apache HBase (TM)
@@ -306,7 +306,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 


[21/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.AssignmentProcedureEvent.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.AssignmentProcedureEvent.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.AssignmentProcedureEvent.html
index c8158b5..be1231a 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.AssignmentProcedureEvent.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.AssignmentProcedureEvent.html
@@ -651,512 +651,518 @@
 <span class="sourceLineNo">643</span>   */<a name="line.643"></a>
 <span class="sourceLineNo">644</span>  public HRegionLocation checkReopened(HRegionLocation oldLoc) {<a name="line.644"></a>
 <span class="sourceLineNo">645</span>    RegionStateNode node = getRegionStateNode(oldLoc.getRegion());<a name="line.645"></a>
-<span class="sourceLineNo">646</span>    synchronized (node) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        // in OPEN state before<a name="line.648"></a>
-<span class="sourceLineNo">649</span>        if (node.isInState(State.OPEN)) {<a name="line.649"></a>
-<span class="sourceLineNo">650</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>            // normal case, the region has been reopened<a name="line.651"></a>
-<span class="sourceLineNo">652</span>            return null;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>          } else {<a name="line.653"></a>
-<span class="sourceLineNo">654</span>            // the open seq num does not change, need to reopen again<a name="line.654"></a>
-<span class="sourceLineNo">655</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.655"></a>
-<span class="sourceLineNo">656</span>              node.getOpenSeqNum());<a name="line.656"></a>
-<span class="sourceLineNo">657</span>          }<a name="line.657"></a>
-<span class="sourceLineNo">658</span>        } else {<a name="line.658"></a>
-<span class="sourceLineNo">659</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.659"></a>
-<span class="sourceLineNo">660</span>          // finished maybe, but not a problem).<a name="line.660"></a>
-<span class="sourceLineNo">661</span>          return null;<a name="line.661"></a>
-<span class="sourceLineNo">662</span>        }<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      } else {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>        // in OPENING state before<a name="line.664"></a>
-<span class="sourceLineNo">665</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.666"></a>
-<span class="sourceLineNo">667</span>          // reopened(not finished maybe, but not a problem)<a name="line.667"></a>
-<span class="sourceLineNo">668</span>          return null;<a name="line.668"></a>
-<span class="sourceLineNo">669</span>        } else {<a name="line.669"></a>
-<span class="sourceLineNo">670</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.670"></a>
-<span class="sourceLineNo">671</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.671"></a>
-<span class="sourceLineNo">672</span>            return null;<a name="line.672"></a>
-<span class="sourceLineNo">673</span>          }<a name="line.673"></a>
-<span class="sourceLineNo">674</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.674"></a>
-<span class="sourceLineNo">675</span>          // is changed to OPEN.<a name="line.675"></a>
-<span class="sourceLineNo">676</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.676"></a>
-<span class="sourceLineNo">677</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<a name="line.677"></a>
-<span class="sourceLineNo">678</span>        }<a name="line.678"></a>
-<span class="sourceLineNo">679</span>      }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    }<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  }<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>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<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.690"></a>
-<span class="sourceLineNo">691</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.691"></a>
-<span class="sourceLineNo">692</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.692"></a>
-<span class="sourceLineNo">693</span>   *         {@link State#SPLIT} state.<a name="line.693"></a>
-<span class="sourceLineNo">694</span>   */<a name="line.694"></a>
-<span class="sourceLineNo">695</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.696"></a>
-<span class="sourceLineNo">697</span>      .collect(Collectors.toList());<a name="line.697"></a>
-<span class="sourceLineNo">698</span>  }<a name="line.698"></a>
-<span class="sourceLineNo">699</span><a name="line.699"></a>
-<span class="sourceLineNo">700</span>  /**<a name="line.700"></a>
-<span class="sourceLineNo">701</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * weed out split and offline regions.<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   */<a name="line.705"></a>
-<span class="sourceLineNo">706</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    if (LOG.isTraceEnabled()) {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.713"></a>
-<span class="sourceLineNo">714</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  }<a name="line.715"></a>
-<span class="sourceLineNo">716</span><a name="line.716"></a>
-<span class="sourceLineNo">717</span>  /**<a name="line.717"></a>
-<span class="sourceLineNo">718</span>   * Returns the set of regions hosted by the specified server<a name="line.718"></a>
-<span class="sourceLineNo">719</span>   * @param serverName the server we are interested in<a name="line.719"></a>
-<span class="sourceLineNo">720</span>   * @return set of RegionInfo hosted by the specified server<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   */<a name="line.721"></a>
-<span class="sourceLineNo">722</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.723"></a>
-<span class="sourceLineNo">724</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.724"></a>
-<span class="sourceLineNo">725</span><a name="line.725"></a>
-<span class="sourceLineNo">726</span>    synchronized (serverInfo) {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      return serverInfo.getRegionInfoList();<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><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  // ============================================================================================<a name="line.731"></a>
-<span class="sourceLineNo">732</span>  // Split helpers<a name="line.732"></a>
-<span class="sourceLineNo">733</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  // the ServerStateNode by calling removeServer.<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  // ============================================================================================<a name="line.735"></a>
+<span class="sourceLineNo">646</span>    // HBASE-20921<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // if the oldLoc's state node does not exist, that means the region is<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // merged or split, no need to check it<a name="line.648"></a>
+<span class="sourceLineNo">649</span>    if (node == null) {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>      return null;<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    }<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    synchronized (node) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      if (oldLoc.getSeqNum() &gt;= 0) {<a name="line.653"></a>
+<span class="sourceLineNo">654</span>        // in OPEN state before<a name="line.654"></a>
+<span class="sourceLineNo">655</span>        if (node.isInState(State.OPEN)) {<a name="line.655"></a>
+<span class="sourceLineNo">656</span>          if (node.getOpenSeqNum() &gt; oldLoc.getSeqNum()) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>            // normal case, the region has been reopened<a name="line.657"></a>
+<span class="sourceLineNo">658</span>            return null;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>          } else {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>            // the open seq num does not change, need to reopen again<a name="line.660"></a>
+<span class="sourceLineNo">661</span>            return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(),<a name="line.661"></a>
+<span class="sourceLineNo">662</span>              node.getOpenSeqNum());<a name="line.662"></a>
+<span class="sourceLineNo">663</span>          }<a name="line.663"></a>
+<span class="sourceLineNo">664</span>        } else {<a name="line.664"></a>
+<span class="sourceLineNo">665</span>          // the state has been changed so we can make sure that the region has been reopened(not<a name="line.665"></a>
+<span class="sourceLineNo">666</span>          // finished maybe, but not a problem).<a name="line.666"></a>
+<span class="sourceLineNo">667</span>          return null;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      } else {<a name="line.669"></a>
+<span class="sourceLineNo">670</span>        // in OPENING state before<a name="line.670"></a>
+<span class="sourceLineNo">671</span>        if (!node.isInState(State.OPEN, State.OPENING)) {<a name="line.671"></a>
+<span class="sourceLineNo">672</span>          // not in OPEN or OPENING state, then we can make sure that the region has been<a name="line.672"></a>
+<span class="sourceLineNo">673</span>          // reopened(not finished maybe, but not a problem)<a name="line.673"></a>
+<span class="sourceLineNo">674</span>          return null;<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        } else {<a name="line.675"></a>
+<span class="sourceLineNo">676</span>          if (!node.getRegionLocation().equals(oldLoc.getServerName())) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>            // the region has been moved, so we can make sure that the region has been reopened.<a name="line.677"></a>
+<span class="sourceLineNo">678</span>            return null;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>          }<a name="line.679"></a>
+<span class="sourceLineNo">680</span>          // normal case, we are still in OPENING state, or the reopen has been opened and the state<a name="line.680"></a>
+<span class="sourceLineNo">681</span>          // is changed to OPEN.<a name="line.681"></a>
+<span class="sourceLineNo">682</span>          long openSeqNum = node.isInState(State.OPEN) ? node.getOpenSeqNum() : -1;<a name="line.682"></a>
+<span class="sourceLineNo">683</span>          return new HRegionLocation(node.getRegionInfo(), node.getRegionLocation(), openSeqNum);<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>  /**<a name="line.689"></a>
+<span class="sourceLineNo">690</span>   * @return Return online regions of table; does not include OFFLINE or SPLITTING regions.<a name="line.690"></a>
+<span class="sourceLineNo">691</span>   */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>  public List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, boolean offline) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>    return getRegionsOfTable(table, state -&gt; include(state, offline));<a name="line.693"></a>
+<span class="sourceLineNo">694</span>  }<a name="line.694"></a>
+<span class="sourceLineNo">695</span><a name="line.695"></a>
+<span class="sourceLineNo">696</span>  /**<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return Return the regions of the table; does not include OFFLINE unless you set<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   *         &lt;code&gt;offline&lt;/code&gt; to true. Does not include regions that are in the<a name="line.698"></a>
+<span class="sourceLineNo">699</span>   *         {@link State#SPLIT} state.<a name="line.699"></a>
+<span class="sourceLineNo">700</span>   */<a name="line.700"></a>
+<span class="sourceLineNo">701</span>  private List&lt;RegionInfo&gt; getRegionsOfTable(TableName table, Predicate&lt;RegionStateNode&gt; filter) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>    return getTableRegionStateNodes(table).stream().filter(filter).map(n -&gt; n.getRegionInfo())<a name="line.702"></a>
+<span class="sourceLineNo">703</span>      .collect(Collectors.toList());<a name="line.703"></a>
+<span class="sourceLineNo">704</span>  }<a name="line.704"></a>
+<span class="sourceLineNo">705</span><a name="line.705"></a>
+<span class="sourceLineNo">706</span>  /**<a name="line.706"></a>
+<span class="sourceLineNo">707</span>   * Utility. Whether to include region in list of regions. Default is to<a name="line.707"></a>
+<span class="sourceLineNo">708</span>   * weed out split and offline regions.<a name="line.708"></a>
+<span class="sourceLineNo">709</span>   * @return True if we should include the &lt;code&gt;node&lt;/code&gt; (do not include<a name="line.709"></a>
+<span class="sourceLineNo">710</span>   * if split or offline unless &lt;code&gt;offline&lt;/code&gt; is set to true.<a name="line.710"></a>
+<span class="sourceLineNo">711</span>   */<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  boolean include(final RegionStateNode node, final boolean offline) {<a name="line.712"></a>
+<span class="sourceLineNo">713</span>    if (LOG.isTraceEnabled()) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>      LOG.trace("WORKING ON " + node + " " + node.getRegionInfo());<a name="line.714"></a>
+<span class="sourceLineNo">715</span>    }<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    if (node.isInState(State.SPLIT)) return false;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>    if (node.isInState(State.OFFLINE) &amp;&amp; !offline) return false;<a name="line.717"></a>
+<span class="sourceLineNo">718</span>    final RegionInfo hri = node.getRegionInfo();<a name="line.718"></a>
+<span class="sourceLineNo">719</span>    return (!hri.isOffline() &amp;&amp; !hri.isSplit()) ||<a name="line.719"></a>
+<span class="sourceLineNo">720</span>        ((hri.isOffline() || hri.isSplit()) &amp;&amp; offline);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>  }<a name="line.721"></a>
+<span class="sourceLineNo">722</span><a name="line.722"></a>
+<span class="sourceLineNo">723</span>  /**<a name="line.723"></a>
+<span class="sourceLineNo">724</span>   * Returns the set of regions hosted by the specified server<a name="line.724"></a>
+<span class="sourceLineNo">725</span>   * @param serverName the server we are interested in<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * @return set of RegionInfo hosted by the specified server<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   */<a name="line.727"></a>
+<span class="sourceLineNo">728</span>  public List&lt;RegionInfo&gt; getServerRegionInfoSet(final ServerName serverName) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>    final ServerStateNode serverInfo = getServerNode(serverName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (serverInfo == null) return Collections.emptyList();<a name="line.730"></a>
+<span class="sourceLineNo">731</span><a name="line.731"></a>
+<span class="sourceLineNo">732</span>    synchronized (serverInfo) {<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return serverInfo.getRegionInfoList();<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>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.738"></a>
-<span class="sourceLineNo">739</span>    synchronized (serverNode) {<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      serverNode.setState(state);<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
-<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
-<span class="sourceLineNo">743</span><a name="line.743"></a>
-<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
-<span class="sourceLineNo">745</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.745"></a>
-<span class="sourceLineNo">746</span>   * @see #metaLogSplit(ServerName)<a name="line.746"></a>
-<span class="sourceLineNo">747</span>   */<a name="line.747"></a>
-<span class="sourceLineNo">748</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    setServerState(serverName, ServerState.SPLITTING_META);<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>  /**<a name="line.752"></a>
-<span class="sourceLineNo">753</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.753"></a>
-<span class="sourceLineNo">754</span>   * @see #metaLogSplitting(ServerName)<a name="line.754"></a>
-<span class="sourceLineNo">755</span>   */<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  public void metaLogSplit(ServerName serverName) {<a name="line.756"></a>
-<span class="sourceLineNo">757</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.757"></a>
-<span class="sourceLineNo">758</span>  }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>  /**<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * Call this when we start log splitting for a crashed Server.<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   * @see #logSplit(ServerName)<a name="line.762"></a>
-<span class="sourceLineNo">763</span>   */<a name="line.763"></a>
-<span class="sourceLineNo">764</span>  public void logSplitting(final ServerName serverName) {<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.765"></a>
-<span class="sourceLineNo">766</span>  }<a name="line.766"></a>
-<span class="sourceLineNo">767</span><a name="line.767"></a>
-<span class="sourceLineNo">768</span>  /**<a name="line.768"></a>
-<span class="sourceLineNo">769</span>   * Called after we've split all logs on a crashed Server.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>   * @see #logSplitting(ServerName)<a name="line.770"></a>
-<span class="sourceLineNo">771</span>   */<a name="line.771"></a>
-<span class="sourceLineNo">772</span>  public void logSplit(final ServerName serverName) {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    setServerState(serverName, ServerState.OFFLINE);<a name="line.773"></a>
-<span class="sourceLineNo">774</span>  }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    synchronized (regionNode) {<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      regionNode.setState(state);<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><a name="line.782"></a>
-<span class="sourceLineNo">783</span>  // ============================================================================================<a name="line.783"></a>
-<span class="sourceLineNo">784</span>  //  TODO:<a name="line.784"></a>
-<span class="sourceLineNo">785</span>  // ============================================================================================<a name="line.785"></a>
-<span class="sourceLineNo">786</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      if (!node.isInTransition()) {<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        result.add(node.getRegionInfo());<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span>    }<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    if (region != null) {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      synchronized (region) {<a name="line.799"></a>
-<span class="sourceLineNo">800</span>        return region.isInState(state);<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>    return false;<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.807"></a>
-<span class="sourceLineNo">808</span>  }<a name="line.808"></a>
-<span class="sourceLineNo">809</span><a name="line.809"></a>
-<span class="sourceLineNo">810</span>  /**<a name="line.810"></a>
-<span class="sourceLineNo">811</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.811"></a>
-<span class="sourceLineNo">812</span>   */<a name="line.812"></a>
-<span class="sourceLineNo">813</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.813"></a>
-<span class="sourceLineNo">814</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.814"></a>
-<span class="sourceLineNo">815</span>  }<a name="line.815"></a>
-<span class="sourceLineNo">816</span><a name="line.816"></a>
-<span class="sourceLineNo">817</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.817"></a>
-<span class="sourceLineNo">818</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.818"></a>
-<span class="sourceLineNo">819</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    for (RegionInfo hri: regions) {<a name="line.820"></a>
-<span class="sourceLineNo">821</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>      if (node == null) continue;<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>      // TODO: State.OPEN<a name="line.824"></a>
-<span class="sourceLineNo">825</span>      final ServerName serverName = node.getRegionLocation();<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      if (serverName == null) continue;<a name="line.826"></a>
-<span class="sourceLineNo">827</span><a name="line.827"></a>
-<span class="sourceLineNo">828</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.828"></a>
-<span class="sourceLineNo">829</span>      if (serverRegions == null) {<a name="line.829"></a>
-<span class="sourceLineNo">830</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.830"></a>
-<span class="sourceLineNo">831</span>        result.put(serverName, serverRegions);<a name="line.831"></a>
-<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">737</span>  // ============================================================================================<a name="line.737"></a>
+<span class="sourceLineNo">738</span>  // Split helpers<a name="line.738"></a>
+<span class="sourceLineNo">739</span>  // These methods will only be called in ServerCrashProcedure, and at the end of SCP we will remove<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  // the ServerStateNode by calling removeServer.<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  // ============================================================================================<a name="line.741"></a>
+<span class="sourceLineNo">742</span><a name="line.742"></a>
+<span class="sourceLineNo">743</span>  private void setServerState(ServerName serverName, ServerState state) {<a name="line.743"></a>
+<span class="sourceLineNo">744</span>    ServerStateNode serverNode = getOrCreateServer(serverName);<a name="line.744"></a>
+<span class="sourceLineNo">745</span>    synchronized (serverNode) {<a name="line.745"></a>
+<span class="sourceLineNo">746</span>      serverNode.setState(state);<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    }<a name="line.747"></a>
+<span class="sourceLineNo">748</span>  }<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>  /**<a name="line.750"></a>
+<span class="sourceLineNo">751</span>   * Call this when we start meta log splitting a crashed Server.<a name="line.751"></a>
+<span class="sourceLineNo">752</span>   * @see #metaLogSplit(ServerName)<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   */<a name="line.753"></a>
+<span class="sourceLineNo">754</span>  public void metaLogSplitting(ServerName serverName) {<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    setServerState(serverName, ServerState.SPLITTING_META);<a name="line.755"></a>
+<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
+<span class="sourceLineNo">757</span><a name="line.757"></a>
+<span class="sourceLineNo">758</span>  /**<a name="line.758"></a>
+<span class="sourceLineNo">759</span>   * Called after we've split the meta logs on a crashed Server.<a name="line.759"></a>
+<span class="sourceLineNo">760</span>   * @see #metaLogSplitting(ServerName)<a name="line.760"></a>
+<span class="sourceLineNo">761</span>   */<a name="line.761"></a>
+<span class="sourceLineNo">762</span>  public void metaLogSplit(ServerName serverName) {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    setServerState(serverName, ServerState.SPLITTING_META_DONE);<a name="line.763"></a>
+<span class="sourceLineNo">764</span>  }<a name="line.764"></a>
+<span class="sourceLineNo">765</span><a name="line.765"></a>
+<span class="sourceLineNo">766</span>  /**<a name="line.766"></a>
+<span class="sourceLineNo">767</span>   * Call this when we start log splitting for a crashed Server.<a name="line.767"></a>
+<span class="sourceLineNo">768</span>   * @see #logSplit(ServerName)<a name="line.768"></a>
+<span class="sourceLineNo">769</span>   */<a name="line.769"></a>
+<span class="sourceLineNo">770</span>  public void logSplitting(final ServerName serverName) {<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    setServerState(serverName, ServerState.SPLITTING);<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>  /**<a name="line.774"></a>
+<span class="sourceLineNo">775</span>   * Called after we've split all logs on a crashed Server.<a name="line.775"></a>
+<span class="sourceLineNo">776</span>   * @see #logSplitting(ServerName)<a name="line.776"></a>
+<span class="sourceLineNo">777</span>   */<a name="line.777"></a>
+<span class="sourceLineNo">778</span>  public void logSplit(final ServerName serverName) {<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    setServerState(serverName, ServerState.OFFLINE);<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>  public void updateRegionState(final RegionInfo regionInfo, final State state) {<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    final RegionStateNode regionNode = getOrCreateRegionStateNode(regionInfo);<a name="line.783"></a>
+<span class="sourceLineNo">784</span>    synchronized (regionNode) {<a name="line.784"></a>
+<span class="sourceLineNo">785</span>      regionNode.setState(state);<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    }<a name="line.786"></a>
+<span class="sourceLineNo">787</span>  }<a name="line.787"></a>
+<span class="sourceLineNo">788</span><a name="line.788"></a>
+<span class="sourceLineNo">789</span>  // ============================================================================================<a name="line.789"></a>
+<span class="sourceLineNo">790</span>  //  TODO:<a name="line.790"></a>
+<span class="sourceLineNo">791</span>  // ============================================================================================<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.792"></a>
+<span class="sourceLineNo">793</span>    final List&lt;RegionInfo&gt; result = new ArrayList&lt;RegionInfo&gt;();<a name="line.793"></a>
+<span class="sourceLineNo">794</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>      if (!node.isInTransition()) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>        result.add(node.getRegionInfo());<a name="line.796"></a>
+<span class="sourceLineNo">797</span>      }<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    }<a name="line.798"></a>
+<span class="sourceLineNo">799</span>    return result;<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>  public boolean isRegionInState(final RegionInfo regionInfo, final State... state) {<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (region != null) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      synchronized (region) {<a name="line.805"></a>
+<span class="sourceLineNo">806</span>        return region.isInState(state);<a name="line.806"></a>
+<span class="sourceLineNo">807</span>      }<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    return false;<a name="line.809"></a>
+<span class="sourceLineNo">810</span>  }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>  public boolean isRegionOnline(final RegionInfo regionInfo) {<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    return isRegionInState(regionInfo, State.OPEN);<a name="line.813"></a>
+<span class="sourceLineNo">814</span>  }<a name="line.814"></a>
+<span class="sourceLineNo">815</span><a name="line.815"></a>
+<span class="sourceLineNo">816</span>  /**<a name="line.816"></a>
+<span class="sourceLineNo">817</span>   * @return True if region is offline (In OFFLINE or CLOSED state).<a name="line.817"></a>
+<span class="sourceLineNo">818</span>   */<a name="line.818"></a>
+<span class="sourceLineNo">819</span>  public boolean isRegionOffline(final RegionInfo regionInfo) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return isRegionInState(regionInfo, State.OFFLINE, State.CLOSED);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; getSnapShotOfAssignment(<a name="line.823"></a>
+<span class="sourceLineNo">824</span>      final Collection&lt;RegionInfo&gt; regions) {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; result = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    for (RegionInfo hri: regions) {<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      final RegionStateNode node = getRegionStateNode(hri);<a name="line.827"></a>
+<span class="sourceLineNo">828</span>      if (node == null) continue;<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>      // TODO: State.OPEN<a name="line.830"></a>
+<span class="sourceLineNo">831</span>      final ServerName serverName = node.getRegionLocation();<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      if (serverName == null) continue;<a name="line.832"></a>
 <span class="sourceLineNo">833</span><a name="line.833"></a>
-<span class="sourceLineNo">834</span>      serverRegions.add(node.getRegionInfo());<a name="line.834"></a>
-<span class="sourceLineNo">835</span>    }<a name="line.835"></a>
-<span class="sourceLineNo">836</span>    return result;<a name="line.836"></a>
-<span class="sourceLineNo">837</span>  }<a name="line.837"></a>
-<span class="sourceLineNo">838</span><a name="line.838"></a>
-<span class="sourceLineNo">839</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.839"></a>
-<span class="sourceLineNo">840</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.840"></a>
-<span class="sourceLineNo">841</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.841"></a>
-<span class="sourceLineNo">842</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    }<a name="line.843"></a>
-<span class="sourceLineNo">844</span>    return assignments;<a name="line.844"></a>
-<span class="sourceLineNo">845</span>  }<a name="line.845"></a>
-<span class="sourceLineNo">846</span><a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    final State[] states = State.values();<a name="line.848"></a>
-<span class="sourceLineNo">849</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.849"></a>
-<span class="sourceLineNo">850</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.850"></a>
-<span class="sourceLineNo">851</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.852"></a>
-<span class="sourceLineNo">853</span>    }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>      if (node.getTable().equals(tableName)) {<a name="line.856"></a>
-<span class="sourceLineNo">857</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.857"></a>
-<span class="sourceLineNo">858</span>      }<a name="line.858"></a>
+<span class="sourceLineNo">834</span>      List&lt;RegionInfo&gt; serverRegions = result.get(serverName);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>      if (serverRegions == null) {<a name="line.835"></a>
+<span class="sourceLineNo">836</span>        serverRegions = new ArrayList&lt;RegionInfo&gt;();<a name="line.836"></a>
+<span class="sourceLineNo">837</span>        result.put(serverName, serverRegions);<a name="line.837"></a>
+<span class="sourceLineNo">838</span>      }<a name="line.838"></a>
+<span class="sourceLineNo">839</span><a name="line.839"></a>
+<span class="sourceLineNo">840</span>      serverRegions.add(node.getRegionInfo());<a name="line.840"></a>
+<span class="sourceLineNo">841</span>    }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>    return result;<a name="line.842"></a>
+<span class="sourceLineNo">843</span>  }<a name="line.843"></a>
+<span class="sourceLineNo">844</span><a name="line.844"></a>
+<span class="sourceLineNo">845</span>  public Map&lt;RegionInfo, ServerName&gt; getRegionAssignments() {<a name="line.845"></a>
+<span class="sourceLineNo">846</span>    final HashMap&lt;RegionInfo, ServerName&gt; assignments = new HashMap&lt;RegionInfo, ServerName&gt;();<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.847"></a>
+<span class="sourceLineNo">848</span>      assignments.put(node.getRegionInfo(), node.getRegionLocation());<a name="line.848"></a>
+<span class="sourceLineNo">849</span>    }<a name="line.849"></a>
+<span class="sourceLineNo">850</span>    return assignments;<a name="line.850"></a>
+<span class="sourceLineNo">851</span>  }<a name="line.851"></a>
+<span class="sourceLineNo">852</span><a name="line.852"></a>
+<span class="sourceLineNo">853</span>  public Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; getRegionByStateOfTable(TableName tableName) {<a name="line.853"></a>
+<span class="sourceLineNo">854</span>    final State[] states = State.values();<a name="line.854"></a>
+<span class="sourceLineNo">855</span>    final Map&lt;RegionState.State, List&lt;RegionInfo&gt;&gt; tableRegions =<a name="line.855"></a>
+<span class="sourceLineNo">856</span>        new HashMap&lt;State, List&lt;RegionInfo&gt;&gt;(states.length);<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    for (int i = 0; i &lt; states.length; ++i) {<a name="line.857"></a>
+<span class="sourceLineNo">858</span>      tableRegions.put(states[i], new ArrayList&lt;RegionInfo&gt;());<a name="line.858"></a>
 <span class="sourceLineNo">859</span>    }<a name="line.859"></a>
-<span class="sourceLineNo">860</span>    return tableRegions;<a name="line.860"></a>
-<span class="sourceLineNo">861</span>  }<a name="line.861"></a>
-<span class="sourceLineNo">862</span><a name="line.862"></a>
-<span class="sourceLineNo">863</span>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.863"></a>
-<span class="sourceLineNo">864</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.864"></a>
-<span class="sourceLineNo">865</span>    if (region != null) {<a name="line.865"></a>
-<span class="sourceLineNo">866</span>      synchronized (region) {<a name="line.866"></a>
-<span class="sourceLineNo">867</span>        ServerName server = region.getRegionLocation();<a name="line.867"></a>
-<span class="sourceLineNo">868</span>        return server != null ? server : region.getLastHost();<a name="line.868"></a>
-<span class="sourceLineNo">869</span>      }<a name="line.869"></a>
-<span class="sourceLineNo">870</span>    }<a name="line.870"></a>
-<span class="sourceLineNo">871</span>    return null;<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>  /**<a name="line.874"></a>
-<span class="sourceLineNo">875</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.875"></a>
-<span class="sourceLineNo">876</span>   * Can't let out original since it can change and at least the load balancer<a name="line.876"></a>
-<span class="sourceLineNo">877</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * @return A clone of current assignments by table.<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.882"></a>
-<span class="sourceLineNo">883</span>      final boolean forceByCluster) {<a name="line.883"></a>
-<span class="sourceLineNo">884</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.884"></a>
-<span class="sourceLineNo">885</span><a name="line.885"></a>
-<span class="sourceLineNo">886</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.886"></a>
-<span class="sourceLineNo">887</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.888"></a>
-<span class="sourceLineNo">889</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    }<a name="line.890"></a>
+<span class="sourceLineNo">860</span><a name="line.860"></a>
+<span class="sourceLineNo">861</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.861"></a>
+<span class="sourceLineNo">862</span>      if (node.getTable().equals(tableName)) {<a name="line.862"></a>
+<span class="sourceLineNo">863</span>        tableRegions.get(node.getState()).add(node.getRegionInfo());<a name="line.863"></a>
+<span class="sourceLineNo">864</span>      }<a name="line.864"></a>
+<span class="sourceLineNo">865</span>    }<a name="line.865"></a>
+<span class="sourceLineNo">866</span>    return tableRegions;<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>  public ServerName getRegionServerOfRegion(final RegionInfo regionInfo) {<a name="line.869"></a>
+<span class="sourceLineNo">870</span>    final RegionStateNode region = getRegionStateNode(regionInfo);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>    if (region != null) {<a name="line.871"></a>
+<span class="sourceLineNo">872</span>      synchronized (region) {<a name="line.872"></a>
+<span class="sourceLineNo">873</span>        ServerName server = region.getRegionLocation();<a name="line.873"></a>
+<span class="sourceLineNo">874</span>        return server != null ? server : region.getLastHost();<a name="line.874"></a>
+<span class="sourceLineNo">875</span>      }<a name="line.875"></a>
+<span class="sourceLineNo">876</span>    }<a name="line.876"></a>
+<span class="sourceLineNo">877</span>    return null;<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>  /**<a name="line.880"></a>
+<span class="sourceLineNo">881</span>   * This is an EXPENSIVE clone.  Cloning though is the safest thing to do.<a name="line.881"></a>
+<span class="sourceLineNo">882</span>   * Can't let out original since it can change and at least the load balancer<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * wants to iterate this exported list.  We need to synchronize on regions<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * since all access to this.servers is under a lock on this.regions.<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * @param forceByCluster a flag to force to aggregate the server-load to the cluster level<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   * @return A clone of current assignments by table.<a name="line.886"></a>
+<span class="sourceLineNo">887</span>   */<a name="line.887"></a>
+<span class="sourceLineNo">888</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable(<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      final boolean forceByCluster) {<a name="line.889"></a>
+<span class="sourceLineNo">890</span>    if (!forceByCluster) return getAssignmentsByTable();<a name="line.890"></a>
 <span class="sourceLineNo">891</span><a name="line.891"></a>
-<span class="sourceLineNo">892</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.892"></a>
-<span class="sourceLineNo">893</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.893"></a>
-<span class="sourceLineNo">894</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.894"></a>
-<span class="sourceLineNo">895</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.895"></a>
-<span class="sourceLineNo">896</span>    return result;<a name="line.896"></a>
-<span class="sourceLineNo">897</span>  }<a name="line.897"></a>
-<span class="sourceLineNo">898</span><a name="line.898"></a>
-<span class="sourceLineNo">899</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.899"></a>
-<span class="sourceLineNo">900</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.900"></a>
-<span class="sourceLineNo">901</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.901"></a>
-<span class="sourceLineNo">902</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.902"></a>
-<span class="sourceLineNo">903</span>      if (tableResult == null) {<a name="line.903"></a>
-<span class="sourceLineNo">904</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.904"></a>
-<span class="sourceLineNo">905</span>        result.put(node.getTable(), tableResult);<a name="line.905"></a>
-<span class="sourceLineNo">906</span>      }<a name="line.906"></a>
-<span class="sourceLineNo">907</span><a name="line.907"></a>
-<span class="sourceLineNo">908</span>      final ServerName serverName = node.getRegionLocation();<a name="line.908"></a>
-<span class="sourceLineNo">909</span>      if (serverName == null) {<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        LOG.info("Skipping, no server for " + node);<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        continue;<a name="line.911"></a>
+<span class="sourceLineNo">892</span>    final HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt; ensemble =<a name="line.892"></a>
+<span class="sourceLineNo">893</span>      new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;(serverMap.size());<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    for (ServerStateNode serverNode: serverMap.values()) {<a name="line.894"></a>
+<span class="sourceLineNo">895</span>      ensemble.put(serverNode.getServerName(), serverNode.getRegionInfoList());<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    }<a name="line.896"></a>
+<span class="sourceLineNo">897</span><a name="line.897"></a>
+<span class="sourceLineNo">898</span>    // TODO: can we use Collections.singletonMap(HConstants.ENSEMBLE_TABLE_NAME, ensemble)?<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result =<a name="line.899"></a>
+<span class="sourceLineNo">900</span>      new HashMap&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt;(1);<a name="line.900"></a>
+<span class="sourceLineNo">901</span>    result.put(HConstants.ENSEMBLE_TABLE_NAME, ensemble);<a name="line.901"></a>
+<span class="sourceLineNo">902</span>    return result;<a name="line.902"></a>
+<span class="sourceLineNo">903</span>  }<a name="line.903"></a>
+<span class="sourceLineNo">904</span><a name="line.904"></a>
+<span class="sourceLineNo">905</span>  public Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; getAssignmentsByTable() {<a name="line.905"></a>
+<span class="sourceLineNo">906</span>    final Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; result = new HashMap&lt;&gt;();<a name="line.906"></a>
+<span class="sourceLineNo">907</span>    for (RegionStateNode node: regionsMap.values()) {<a name="line.907"></a>
+<span class="sourceLineNo">908</span>      Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; tableResult = result.get(node.getTable());<a name="line.908"></a>
+<span class="sourceLineNo">909</span>      if (tableResult == null) {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>        tableResult = new HashMap&lt;ServerName, List&lt;RegionInfo&gt;&gt;();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>        result.put(node.getTable(), tableResult);<a name="line.911"></a>
 <span class="sourceLineNo">912</span>      }<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      if (serverResult == null) {<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.915"></a>
-<span class="sourceLineNo">916</span>        tableResult.put(serverName, serverResult);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      }<a name="line.917"></a>
-<span class="sourceLineNo">918</span><a name="line.918"></a>
-<span class="sourceLineNo">919</span>      serverResult.add(node.getRegionInfo());<a name="line.919"></a>
-<span class="sourceLineNo">920</span>    }<a name="line.920"></a>
-<span class="sourceLineNo">921</span>    // Add online servers with no assignment for the table.<a name="line.921"></a>
-<span class="sourceLineNo">922</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.922"></a>
-<span class="sourceLineNo">923</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.923"></a>
-<span class="sourceLineNo">924</span>          if (!table.containsKey(svr)) {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.925"></a>
-<span class="sourceLineNo">926</span>          }<a name="line.926"></a>
-<span class="sourceLineNo">927</span>        }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    }<a name="line.928"></a>
-<span class="sourceLineNo">929</span>    return result;<a name="line.929"></a>
-<span class="sourceLineNo">930</span>  }<a name="line.930"></a>
-<span class="sourceLineNo">931</span><a name="line.931"></a>
-<span class="sourceLineNo">932</span>  // ==========================================================================<a name="line.932"></a>
-<span class="sourceLineNo">933</span>  //  Region in transition helpers<a name="line.933"></a>
-<span class="sourceLineNo">934</span>  // ==========================================================================<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.935"></a>
-<span class="sourceLineNo">936</span>      final RegionTransitionProcedure procedure) {<a name="line.936"></a>
-<span class="sourceLineNo">937</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.937"></a>
-<span class="sourceLineNo">938</span><a name="line.938"></a>
-<span class="sourceLineNo">939</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.939"></a>
-<span class="sourceLineNo">940</span>    return true;<a name="line.940"></a>
-<span class="sourceLineNo">941</span>  }<a name="line.941"></a>
-<span class="sourceLineNo">942</span><a name="line.942"></a>
-<span class="sourceLineNo">943</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.943"></a>
-<span class="sourceLineNo">944</span>      final RegionTransitionProcedure procedure) {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.945"></a>
-<span class="sourceLineNo">946</span>    regionNode.unsetProcedure(procedure);<a name="line.946"></a>
+<span class="sourceLineNo">913</span><a name="line.913"></a>
+<span class="sourceLineNo">914</span>      final ServerName serverName = node.getRegionLocation();<a name="line.914"></a>
+<span class="sourceLineNo">915</span>      if (serverName == null) {<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        LOG.info("Skipping, no server for " + node);<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        continue;<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      List&lt;RegionInfo&gt; serverResult = tableResult.get(serverName);<a name="line.919"></a>
+<span class="sourceLineNo">920</span>      if (serverResult == null) {<a name="line.920"></a>
+<span class="sourceLineNo">921</span>        serverResult = new ArrayList&lt;RegionInfo&gt;();<a name="line.921"></a>
+<span class="sourceLineNo">922</span>        tableResult.put(serverName, serverResult);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>      }<a name="line.923"></a>
+<span class="sourceLineNo">924</span><a name="line.924"></a>
+<span class="sourceLineNo">925</span>      serverResult.add(node.getRegionInfo());<a name="line.925"></a>
+<span class="sourceLineNo">926</span>    }<a name="line.926"></a>
+<span class="sourceLineNo">927</span>    // Add online servers with no assignment for the table.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>    for (Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; table: result.values()) {<a name="line.928"></a>
+<span class="sourceLineNo">929</span>        for (ServerName svr : serverMap.keySet()) {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>          if (!table.containsKey(svr)) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>            table.put(svr, new ArrayList&lt;RegionInfo&gt;());<a name="line.931"></a>
+<span class="sourceLineNo">932</span>          }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>        }<a name="line.933"></a>
+<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
+<span class="sourceLineNo">935</span>    return result;<a name="line.935"></a>
+<span class="sourceLineNo">936</span>  }<a name="line.936"></a>
+<span class="sourceLineNo">937</span><a name="line.937"></a>
+<span class="sourceLineNo">938</span>  // ==========================================================================<a name="line.938"></a>
+<span class="sourceLineNo">939</span>  //  Region in transition helpers<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  // ==========================================================================<a name="line.940"></a>
+<span class="sourceLineNo">941</span>  protected boolean addRegionInTransition(final RegionStateNode regionNode,<a name="line.941"></a>
+<span class="sourceLineNo">942</span>      final RegionTransitionProcedure procedure) {<a name="line.942"></a>
+<span class="sourceLineNo">943</span>    if (procedure != null &amp;&amp; !regionNode.setProcedure(procedure)) return false;<a name="line.943"></a>
+<span class="sourceLineNo">944</span><a name="line.944"></a>
+<span class="sourceLineNo">945</span>    regionInTransition.put(regionNode.getRegionInfo(), regionNode);<a name="line.945"></a>
+<span class="sourceLineNo">946</span>    return true;<a name="line.946"></a>
 <span class="sourceLineNo">947</span>  }<a name="line.947"></a>
 <span class="sourceLineNo">948</span><a name="line.948"></a>
-<span class="sourceLineNo">949</span>  public boolean hasRegionsInTransition() {<a name="line.949"></a>
-<span class="sourceLineNo">950</span>    return !regionInTransition.isEmpty();<a name="line.950"></a>
-<span class="sourceLineNo">951</span>  }<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    return node != null ? node.isInTransition() : false;<a name="line.955"></a>
-<span class="sourceLineNo">956</span>  }<a name="line.956"></a>
-<span class="sourceLineNo">957</span><a name="line.957"></a>
-<span class="sourceLineNo">958</span>  /**<a name="line.958"></a>
-<span class="sourceLineNo">959</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.959"></a>
-<span class="sourceLineNo">960</span>   */<a name="line.960"></a>
-<span class="sourceLineNo">961</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.961"></a>
-<span class="sourceLineNo">962</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.962"></a>
-<span class="sourceLineNo">963</span>    if (node == null) return null;<a name="line.963"></a>
-<span class="sourceLineNo">964</span>    return node.getProcedure();<a name="line.964"></a>
-<span class="sourceLineNo">965</span>  }<a name="line.965"></a>
-<span class="sourceLineNo">966</span><a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.967"></a>
+<span class="sourceLineNo">949</span>  protected void removeRegionInTransition(final RegionStateNode regionNode,<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      final RegionTransitionProcedure procedure) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>    regionInTransition.remove(regionNode.getRegionInfo());<a name="line.951"></a>
+<span class="sourceLineNo">952</span>    regionNode.unsetProcedure(procedure);<a name="line.952"></a>
+<span class="sourceLineNo">953</span>  }<a name="line.953"></a>
+<span class="sourceLineNo">954</span><a name="line.954"></a>
+<span class="sourceLineNo">955</span>  public boolean hasRegionsInTransition() {<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    return !regionInTransition.isEmpty();<a name="line.956"></a>
+<span class="sourceLineNo">957</span>  }<a name="line.957"></a>
+<span class="sourceLineNo">958</span><a name="line.958"></a>
+<span class="sourceLineNo">959</span>  public boolean isRegionInTransition(final RegionInfo regionInfo) {<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    final RegionStateNode node = regionInTransition.get(regionInfo);<a name="line.960"></a>
+<span class="sourceLineNo">961</span>    return node != null ? node.isInTransition() : false;<a name="line.961"></a>
+<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
+<span class="sourceLineNo">963</span><a name="line.963"></a>
+<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
+<span class="sourceLineNo">965</span>   * @return If a procedure-in-transition for &lt;code&gt;hri&lt;/code&gt;, return it else null.<a name="line.965"></a>
+<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  public RegionTransitionProcedure getRegionTransitionProcedure(final RegionInfo hri) {<a name="line.967"></a>
 <span class="sourceLineNo">968</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.968"></a>
 <span class="sourceLineNo">969</span>    if (node == null) return null;<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>    synchronized (node) {<a name="line.971"></a>
-<span class="sourceLineNo">972</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.972"></a>
-<span class="sourceLineNo">973</span>    }<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
-<span class="sourceLineNo">975</span><a name="line.975"></a>
-<span class="sourceLineNo">976</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Get the number of regions in transition.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public int getRegionsInTransitionCount() {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    return regionInTransition.size();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>  }<a name="line.985"></a>
-<span class="sourceLineNo">986</span><a name="line.986"></a>
-<span class="sourceLineNo">987</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.987"></a>
-<span class="sourceLineNo">988</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.988"></a>
-<span class="sourceLineNo">989</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>      rit.add(node.toRegionState());<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    }<a name="line.991"></a>
-<span class="sourceLineNo">992</span>    return rit;<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.995"></a>
-<span class="sourceLineNo">996</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.996"></a>
-<span class="sourceLineNo">997</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.997"></a>
-<span class="sourceLineNo">998</span>      rit.add(node.toRegionState());<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    }<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>    return rit;<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>  }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span><a name="line.1002"></a>
-<span class="sourceLineNo">1003</span>  // ==========================================================================<a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  //  Region offline helpers<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>  // ==========================================================================<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  // TODO: Unused.<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>    regionOffline.remove(regionInfo);<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span><a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>  // ==========================================================================<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  //  Region FAIL_OPEN helpers<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span>  // ==========================================================================<a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public static final class RegionFailedOpen {<a name="line.1020"></a>
-<span class="sourceLineNo">1021</span>    private final RegionStateNode regionNode;<a name="line.1021"></a>
+<span class="sourceLineNo">970</span>    return node.getProcedure();<a name="line.970"></a>
+<span class="sourceLineNo">971</span>  }<a name="line.971"></a>
+<span class="sourceLineNo">972</span><a name="line.972"></a>
+<span class="sourceLineNo">973</span>  public RegionState getRegionTransitionState(final RegionInfo hri) {<a name="line.973"></a>
+<span class="sourceLineNo">974</span>    RegionStateNode node = regionInTransition.get(hri);<a name="line.974"></a>
+<span class="sourceLineNo">975</span>    if (node == null) return null;<a name="line.975"></a>
+<span class="sourceLineNo">976</span><a name="line.976"></a>
+<span class="sourceLineNo">977</span>    synchronized (node) {<a name="line.977"></a>
+<span class="sourceLineNo">978</span>      return node.isInTransition() ? node.toRegionState() : null;<a name="line.978"></a>
+<span class="sourceLineNo">979</span>    }<a name="line.979"></a>
+<span class="sourceLineNo">980</span>  }<a name="line.980"></a>
+<span class="sourceLineNo">981</span><a name="line.981"></a>
+<span class="sourceLineNo">982</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.982"></a>
+<span class="sourceLineNo">983</span>    return new ArrayList&lt;RegionStateNode&gt;(regionInTransition.values());<a name="line.983"></a>
+<span class="sourceLineNo">984</span>  }<a name="line.984"></a>
+<span class="sourceLineNo">985</span><a name="line.985"></a>
+<span class="sourceLineNo">986</span>  /**<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   * Get the number of regions in transition.<a name="line.987"></a>
+<span class="sourceLineNo">988</span>   */<a name="line.988"></a>
+<span class="sourceLineNo">989</span>  public int getRegionsInTransitionCount() {<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    return regionInTransition.size();<a name="line.990"></a>
+<span class="sourceLineNo">991</span>  }<a name="line.991"></a>
+<span class="sourceLineNo">992</span><a name="line.992"></a>
+<span class="sourceLineNo">993</span>  public List&lt;RegionState&gt; getRegionsStateInTransition() {<a name="line.993"></a>
+<span class="sourceLineNo">994</span>    final List&lt;RegionState&gt; rit = new ArrayList&lt;RegionState&gt;(regionInTransition.size());<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.995"></a>
+<span class="sourceLineNo">996</span>      rit.add(node.toRegionState());<a name="line.996"></a>
+<span class="sourceLineNo">997</span>    }<a name="line.997"></a>
+<span class="sourceLineNo">998</span>    return rit;<a name="line.998"></a>
+<span class="sourceLineNo">999</span>  }<a name="line.999"></a>
+<span class="sourceLineNo">1000</span><a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>  public SortedSet&lt;RegionState&gt; getRegionsInTransitionOrderedByTimestamp() {<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>    final SortedSet&lt;RegionState&gt; rit = new TreeSet&lt;RegionState&gt;(REGION_STATE_STAMP_COMPARATOR);<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>    for (RegionStateNode node: regionInTransition.values()) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>      rit.add(node.toRegionState());<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>    }<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    return rit;<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  // ==========================================================================<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>  //  Region offline helpers<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>  // ==========================================================================<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  // TODO: Populated when we read meta but regions never make it out of here.<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>  public void addToOfflineRegions(final RegionStateNode regionNode) {<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    LOG.info("Added to offline, CURRENTLY NEVER CLEARED!!! " + regionNode);<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>    regionOffline.put(regionNode.getRegionInfo(), regionNode);<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span>  }<a name="line.1016"></a>
+<span class="sourceLineNo">1017</span><a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>  // TODO: Unused.<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>  public void removeFromOfflineRegions(final RegionInfo regionInfo) {<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>    regionOffline.remove(regionInfo);<a name="line.1020"></a>
+<span class="sourceLineNo">1021</span>  }<a name="line.1021"></a>
 <span class="sourceLineNo">1022</span><a name="line.1022"></a>
-<span class="sourceLineNo">1023</span>    private volatile Exception exception = null;<a name="line.1023"></a>
-<span class="sourceLineNo">1024</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1024"></a>
-<span class="sourceLineNo">1025</span><a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>      this.regionNode = regionNode;<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>    }<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span><a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    public RegionStateNode getRegionStateNode() {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return regionNode;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span><a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    public RegionInfo getRegionInfo() {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      return regionNode.getRegionInfo();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>    }<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span><a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>    public int incrementAndGetRetries() {<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      return this.retries.incrementAndGet();<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>    }<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span><a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>    public int getRetries() {<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>      return retries.get();<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>    }<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span><a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>    public void setException(final Exception exception) {<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      this.exception = exception;<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>    }<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span><a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>    public Exception getException() {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>      return this.exception;<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>    }<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>  }<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span><a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>    if (node == null) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>      node = oldNode != null ? oldNode : newNode;<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>    }<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>    return node;<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>  }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span><a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>  public RegionFailedOpen getFailedOpen(final RegionInfo regionInfo) {<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>    return regionFailedOpen.get(regionInfo.getRegionName());<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>  }<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span><a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>  public void removeFromFailedOpen(final RegionInfo regionInfo) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>    regionFailedOpen.remove(regionInfo.getRegionName());<a name="line.1071"></a>
-<span class="sourceLineNo">1072</span>  }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span><a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>  public List&lt;RegionState&gt; getRegionFailedOpen() {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>    if (regionFailedOpen.isEmpty()) return Collections.emptyList();<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span><a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>    ArrayList&lt;RegionState&gt; regions = new ArrayList&lt;RegionState&gt;(regionFailedOpen.size());<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span>    for (RegionFailedOpen r: regionFailedOpen.values()) {<a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>      regions.add(r.getRegionStateNode().toRegionState());<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>    }<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>    return regions;<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span><a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>  // ==========================================================================<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>  //  Servers<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>  // ==========================================================================<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span><a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>  /**<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>   * Be judicious calling this method. Do it on server register ONLY otherwise<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>   * you could mess up online server accounting. TOOD: Review usage and convert<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>   * to {@link #getServerNode(ServerName)} where we can.<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>   */<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>  public ServerStateNode getOrCreateServer(final ServerName serverName) {<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>    ServerStateNode node = serverMap.get(serverName);<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    if (node == null) {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      node = new ServerStateNode(serverName);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      ServerStateNode oldNode = serverMap.putIfAbsent(serverName, node);<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      node = oldNode != null ? oldNode : node;<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    }<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    return node;<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>  public void removeServer(final ServerName serverName) {<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>    serverMap.remove(serverName);<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  }<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span><a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>  protected ServerStateNode getServerNode(final ServerName serverName) {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    return serverMap.get(serverName);<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>  }<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span><a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>  public double getAverageLoad() {<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>    int numServers = 0;<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>    int totalLoad = 0;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>    for (ServerStateNode node: serverMap.values()) {<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>      totalLoad += node.getRegionCount();<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>      numServers++;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>    }<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>    return numServers == 0 ? 0.0: (double)totalLoad / (double)numServers;<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>  }<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span><a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>  public ServerStateNode addRegionToServer(final RegionStateNode regionNode) {<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>    ServerStateNode serverNode = getOrCreateServer(regionNode.getRegionLocation());<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>    serverNode.addRegion(regionNode);<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    return serverNode;<a name="line.1124"></a>
+<span class="sourceLineNo">1023</span>  // ==========================================================================<a name="line.1023"></a>
+<span class="sourceLineNo">1024</span>  //  Region FAIL_OPEN helpers<a name="line.1024"></a>
+<span class="sourceLineNo">1025</span>  // ==========================================================================<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>  public static final class RegionFailedOpen {<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    private final RegionStateNode regionNode;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span><a name="line.1028"></a>
+<span class="sourceLineNo">1029</span>    private volatile Exception exception = null;<a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>    private AtomicInteger retries = new AtomicInteger();<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span><a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>    public RegionFailedOpen(final RegionStateNode regionNode) {<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>      this.regionNode = regionNode;<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>    }<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span><a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>    public RegionStateNode getRegionStateNode() {<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>      return regionNode;<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    }<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span><a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>    public RegionInfo getRegionInfo() {<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      return regionNode.getRegionInfo();<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>    }<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span><a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>    public int incrementAndGetRetries() {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>      return this.retries.incrementAndGet();<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>    }<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span><a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>    public int getRetries() {<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      return retries.get();<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>    }<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span><a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>    public void setException(final Exception exception) {<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      this.exception = exception;<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>    }<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span><a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>    public Exception getException() {<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>      return this.exception;<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>    }<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>  }<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span><a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>  public RegionFailedOpen addToFailedOpen(final RegionStateNode regionNode) {<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>    final byte[] key = regionNode.getRegionInfo().getRegionName();<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>    RegionFailedOpen node = regionFailedOpen.get(key);<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>    if (node == null) {<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>      RegionFailedOpen newNode = new RegionFailedOpen(regionNode);<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>      RegionFailedOpen oldNode = regionFailedOpen.putIfAbsent(key, newNode);<a name="line.1066"></a>
+<span class="sourceLineNo

<TRUNCATED>

[03/28] hbase-site git commit: Published site at 7178a98258dbb28496c2c4f3fbbf8e552ead8bdb.

Posted by gi...@apache.org.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
index 20cb1c6..92133e5 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html
@@ -23,15 +23,15 @@
 <span class="sourceLineNo">015</span> * See the License for the specific language governing permissions and<a name="line.15"></a>
 <span class="sourceLineNo">016</span> * limitations under the License.<a name="line.16"></a>
 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
-<span class="sourceLineNo">018</span><a name="line.18"></a>
-<span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.procedure2;<a name="line.19"></a>
-<span class="sourceLineNo">020</span><a name="line.20"></a>
-<span class="sourceLineNo">021</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import org.apache.yetus.audience.InterfaceStability;<a name="line.22"></a>
-<span class="sourceLineNo">023</span><a name="line.23"></a>
-<span class="sourceLineNo">024</span>@InterfaceAudience.Private<a name="line.24"></a>
-<span class="sourceLineNo">025</span>@InterfaceStability.Stable<a name="line.25"></a>
-<span class="sourceLineNo">026</span>public class ProcedureSuspendedException extends ProcedureException {<a name="line.26"></a>
+<span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.procedure2;<a name="line.18"></a>
+<span class="sourceLineNo">019</span><a name="line.19"></a>
+<span class="sourceLineNo">020</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.20"></a>
+<span class="sourceLineNo">021</span><a name="line.21"></a>
+<span class="sourceLineNo">022</span>@InterfaceAudience.Private<a name="line.22"></a>
+<span class="sourceLineNo">023</span>public class ProcedureSuspendedException extends ProcedureException {<a name="line.23"></a>
+<span class="sourceLineNo">024</span><a name="line.24"></a>
+<span class="sourceLineNo">025</span>  private static final long serialVersionUID = -8328419627678496269L;<a name="line.25"></a>
+<span class="sourceLineNo">026</span><a name="line.26"></a>
 <span class="sourceLineNo">027</span>  /** default constructor */<a name="line.27"></a>
 <span class="sourceLineNo">028</span>  public ProcedureSuspendedException() {<a name="line.28"></a>
 <span class="sourceLineNo">029</span>    super();<a name="line.29"></a>

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.RSGroupAdminServiceImpl.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.RSGroupAdminServiceImpl.html b/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.RSGroupAdminServiceImpl.html
index 45e689b..3bf5bde 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.RSGroupAdminServiceImpl.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.RSGroupAdminServiceImpl.html
@@ -547,27 +547,29 @@
 <span class="sourceLineNo">539</span>        filter(server -&gt; !notClearedServers.contains(server)).<a name="line.539"></a>
 <span class="sourceLineNo">540</span>        map(ServerName::getAddress).<a name="line.540"></a>
 <span class="sourceLineNo">541</span>        collect(Collectors.toSet());<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    groupAdminServer.removeServers(clearedServer);<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>  public void checkPermission(String request) throws IOException {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    accessChecker.requirePermission(getActiveUser(), request, null, Action.ADMIN);<a name="line.546"></a>
-<span class="sourceLineNo">547</span>  }<a name="line.547"></a>
-<span class="sourceLineNo">548</span><a name="line.548"></a>
-<span class="sourceLineNo">549</span>  /**<a name="line.549"></a>
-<span class="sourceLineNo">550</span>   * Returns the active user to which authorization checks should be applied.<a name="line.550"></a>
-<span class="sourceLineNo">551</span>   * If we are in the context of an RPC call, the remote user is used,<a name="line.551"></a>
-<span class="sourceLineNo">552</span>   * otherwise the currently logged in user is used.<a name="line.552"></a>
-<span class="sourceLineNo">553</span>   */<a name="line.553"></a>
-<span class="sourceLineNo">554</span>  private User getActiveUser() throws IOException {<a name="line.554"></a>
-<span class="sourceLineNo">555</span>    // for non-rpc handling, fallback to system user<a name="line.555"></a>
-<span class="sourceLineNo">556</span>    Optional&lt;User&gt; optionalUser = RpcServer.getRequestUser();<a name="line.556"></a>
-<span class="sourceLineNo">557</span>    if (optionalUser.isPresent()) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>      return optionalUser.get();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    }<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return userProvider.getCurrent();<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>}<a name="line.562"></a>
+<span class="sourceLineNo">542</span>    if(!clearedServer.isEmpty()) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>      groupAdminServer.removeServers(clearedServer);<a name="line.543"></a>
+<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">545</span>  }<a name="line.545"></a>
+<span class="sourceLineNo">546</span><a name="line.546"></a>
+<span class="sourceLineNo">547</span>  public void checkPermission(String request) throws IOException {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    accessChecker.requirePermission(getActiveUser(), request, null, Action.ADMIN);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
+<span class="sourceLineNo">550</span><a name="line.550"></a>
+<span class="sourceLineNo">551</span>  /**<a name="line.551"></a>
+<span class="sourceLineNo">552</span>   * Returns the active user to which authorization checks should be applied.<a name="line.552"></a>
+<span class="sourceLineNo">553</span>   * If we are in the context of an RPC call, the remote user is used,<a name="line.553"></a>
+<span class="sourceLineNo">554</span>   * otherwise the currently logged in user is used.<a name="line.554"></a>
+<span class="sourceLineNo">555</span>   */<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  private User getActiveUser() throws IOException {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>    // for non-rpc handling, fallback to system user<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    Optional&lt;User&gt; optionalUser = RpcServer.getRequestUser();<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    if (optionalUser.isPresent()) {<a name="line.559"></a>
+<span class="sourceLineNo">560</span>      return optionalUser.get();<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    }<a name="line.561"></a>
+<span class="sourceLineNo">562</span>    return userProvider.getCurrent();<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>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html b/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
index 45e689b..3bf5bde 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.html
@@ -547,27 +547,29 @@
 <span class="sourceLineNo">539</span>        filter(server -&gt; !notClearedServers.contains(server)).<a name="line.539"></a>
 <span class="sourceLineNo">540</span>        map(ServerName::getAddress).<a name="line.540"></a>
 <span class="sourceLineNo">541</span>        collect(Collectors.toSet());<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    groupAdminServer.removeServers(clearedServer);<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>  public void checkPermission(String request) throws IOException {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    accessChecker.requirePermission(getActiveUser(), request, null, Action.ADMIN);<a name="line.546"></a>
-<span class="sourceLineNo">547</span>  }<a name="line.547"></a>
-<span class="sourceLineNo">548</span><a name="line.548"></a>
-<span class="sourceLineNo">549</span>  /**<a name="line.549"></a>
-<span class="sourceLineNo">550</span>   * Returns the active user to which authorization checks should be applied.<a name="line.550"></a>
-<span class="sourceLineNo">551</span>   * If we are in the context of an RPC call, the remote user is used,<a name="line.551"></a>
-<span class="sourceLineNo">552</span>   * otherwise the currently logged in user is used.<a name="line.552"></a>
-<span class="sourceLineNo">553</span>   */<a name="line.553"></a>
-<span class="sourceLineNo">554</span>  private User getActiveUser() throws IOException {<a name="line.554"></a>
-<span class="sourceLineNo">555</span>    // for non-rpc handling, fallback to system user<a name="line.555"></a>
-<span class="sourceLineNo">556</span>    Optional&lt;User&gt; optionalUser = RpcServer.getRequestUser();<a name="line.556"></a>
-<span class="sourceLineNo">557</span>    if (optionalUser.isPresent()) {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>      return optionalUser.get();<a name="line.558"></a>
-<span class="sourceLineNo">559</span>    }<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return userProvider.getCurrent();<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>}<a name="line.562"></a>
+<span class="sourceLineNo">542</span>    if(!clearedServer.isEmpty()) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>      groupAdminServer.removeServers(clearedServer);<a name="line.543"></a>
+<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">545</span>  }<a name="line.545"></a>
+<span class="sourceLineNo">546</span><a name="line.546"></a>
+<span class="sourceLineNo">547</span>  public void checkPermission(String request) throws IOException {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    accessChecker.requirePermission(getActiveUser(), request, null, Action.ADMIN);<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
+<span class="sourceLineNo">550</span><a name="line.550"></a>
+<span class="sourceLineNo">551</span>  /**<a name="line.551"></a>
+<span class="sourceLineNo">552</span>   * Returns the active user to which authorization checks should be applied.<a name="line.552"></a>
+<span class="sourceLineNo">553</span>   * If we are in the context of an RPC call, the remote user is used,<a name="line.553"></a>
+<span class="sourceLineNo">554</span>   * otherwise the currently logged in user is used.<a name="line.554"></a>
+<span class="sourceLineNo">555</span>   */<a name="line.555"></a>
+<span class="sourceLineNo">556</span>  private User getActiveUser() throws IOException {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>    // for non-rpc handling, fallback to system user<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    Optional&lt;User&gt; optionalUser = RpcServer.getRequestUser();<a name="line.558"></a>
+<span class="sourceLineNo">559</span>    if (optionalUser.isPresent()) {<a name="line.559"></a>
+<span class="sourceLineNo">560</span>      return optionalUser.get();<a name="line.560"></a>
+<span class="sourceLineNo">561</span>    }<a name="line.561"></a>
+<span class="sourceLineNo">562</span>    return userProvider.getCurrent();<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>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html b/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html
index e3c9d73..18375e0 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.Entry.html
@@ -6,144 +6,143 @@
 </head>
 <body>
 <div class="sourceContainer">
-<pre><span class="sourceLineNo">001</span>/*<a name="line.1"></a>
-<span class="sourceLineNo">002</span> *<a name="line.2"></a>
-<span class="sourceLineNo">003</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.3"></a>
-<span class="sourceLineNo">004</span> * or more contributor license agreements.  See the NOTICE file<a name="line.4"></a>
-<span class="sourceLineNo">005</span> * distributed with this work for additional information<a name="line.5"></a>
-<span class="sourceLineNo">006</span> * regarding copyright ownership.  The ASF licenses this file<a name="line.6"></a>
-<span class="sourceLineNo">007</span> * to you under the Apache License, Version 2.0 (the<a name="line.7"></a>
-<span class="sourceLineNo">008</span> * "License"); you may not use this file except in compliance<a name="line.8"></a>
-<span class="sourceLineNo">009</span> * with the License.  You may obtain a copy of the License at<a name="line.9"></a>
-<span class="sourceLineNo">010</span> *<a name="line.10"></a>
-<span class="sourceLineNo">011</span> *     http://www.apache.org/licenses/LICENSE-2.0<a name="line.11"></a>
-<span class="sourceLineNo">012</span> *<a name="line.12"></a>
-<span class="sourceLineNo">013</span> * Unless required by applicable law or agreed to in writing, software<a name="line.13"></a>
-<span class="sourceLineNo">014</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.14"></a>
-<span class="sourceLineNo">015</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.15"></a>
-<span class="sourceLineNo">016</span> * See the License for the specific language governing permissions and<a name="line.16"></a>
-<span class="sourceLineNo">017</span> * limitations under the License.<a name="line.17"></a>
-<span class="sourceLineNo">018</span> */<a name="line.18"></a>
-<span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.util;<a name="line.19"></a>
-<span class="sourceLineNo">020</span><a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.IOException;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import java.io.InterruptedIOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.concurrent.ConcurrentMap;<a name="line.24"></a>
-<span class="sourceLineNo">025</span><a name="line.25"></a>
-<span class="sourceLineNo">026</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.26"></a>
-<span class="sourceLineNo">027</span><a name="line.27"></a>
-<span class="sourceLineNo">028</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.28"></a>
-<span class="sourceLineNo">029</span><a name="line.29"></a>
-<span class="sourceLineNo">030</span>/**<a name="line.30"></a>
-<span class="sourceLineNo">031</span> * Allows multiple concurrent clients to lock on a numeric id with a minimal<a name="line.31"></a>
-<span class="sourceLineNo">032</span> * memory overhead. The intended usage is as follows:<a name="line.32"></a>
-<span class="sourceLineNo">033</span> *<a name="line.33"></a>
-<span class="sourceLineNo">034</span> * &lt;pre&gt;<a name="line.34"></a>
-<span class="sourceLineNo">035</span> * IdLock.Entry lockEntry = idLock.getLockEntry(id);<a name="line.35"></a>
-<span class="sourceLineNo">036</span> * try {<a name="line.36"></a>
-<span class="sourceLineNo">037</span> *   // User code.<a name="line.37"></a>
-<span class="sourceLineNo">038</span> * } finally {<a name="line.38"></a>
-<span class="sourceLineNo">039</span> *   idLock.releaseLockEntry(lockEntry);<a name="line.39"></a>
-<span class="sourceLineNo">040</span> * }&lt;/pre&gt;<a name="line.40"></a>
-<span class="sourceLineNo">041</span> */<a name="line.41"></a>
-<span class="sourceLineNo">042</span>@InterfaceAudience.Private<a name="line.42"></a>
-<span class="sourceLineNo">043</span>public class IdLock {<a name="line.43"></a>
-<span class="sourceLineNo">044</span><a name="line.44"></a>
-<span class="sourceLineNo">045</span>  /** An entry returned to the client as a lock object */<a name="line.45"></a>
-<span class="sourceLineNo">046</span>  public static class Entry {<a name="line.46"></a>
-<span class="sourceLineNo">047</span>    private final long id;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>    private int numWaiters;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>    private boolean locked = true;<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>    private Entry(long id) {<a name="line.51"></a>
-<span class="sourceLineNo">052</span>      this.id = id;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>    }<a name="line.53"></a>
-<span class="sourceLineNo">054</span><a name="line.54"></a>
-<span class="sourceLineNo">055</span>    @Override<a name="line.55"></a>
-<span class="sourceLineNo">056</span>    public String toString() {<a name="line.56"></a>
-<span class="sourceLineNo">057</span>      return "id=" + id + ", numWaiter=" + numWaiters + ", isLocked="<a name="line.57"></a>
-<span class="sourceLineNo">058</span>          + locked;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    }<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  }<a name="line.60"></a>
-<span class="sourceLineNo">061</span><a name="line.61"></a>
-<span class="sourceLineNo">062</span>  private ConcurrentMap&lt;Long, Entry&gt; map = new ConcurrentHashMap&lt;&gt;();<a name="line.62"></a>
-<span class="sourceLineNo">063</span><a name="line.63"></a>
-<span class="sourceLineNo">064</span>  /**<a name="line.64"></a>
-<span class="sourceLineNo">065</span>   * Blocks until the lock corresponding to the given id is acquired.<a name="line.65"></a>
-<span class="sourceLineNo">066</span>   *<a name="line.66"></a>
-<span class="sourceLineNo">067</span>   * @param id an arbitrary number to lock on<a name="line.67"></a>
-<span class="sourceLineNo">068</span>   * @return an "entry" to pass to {@link #releaseLockEntry(Entry)} to release<a name="line.68"></a>
-<span class="sourceLineNo">069</span>   *         the lock<a name="line.69"></a>
-<span class="sourceLineNo">070</span>   * @throws IOException if interrupted<a name="line.70"></a>
-<span class="sourceLineNo">071</span>   */<a name="line.71"></a>
-<span class="sourceLineNo">072</span>  public Entry getLockEntry(long id) throws IOException {<a name="line.72"></a>
-<span class="sourceLineNo">073</span>    Entry entry = new Entry(id);<a name="line.73"></a>
-<span class="sourceLineNo">074</span>    Entry existing;<a name="line.74"></a>
-<span class="sourceLineNo">075</span>    while ((existing = map.putIfAbsent(entry.id, entry)) != null) {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>      synchronized (existing) {<a name="line.76"></a>
-<span class="sourceLineNo">077</span>        if (existing.locked) {<a name="line.77"></a>
-<span class="sourceLineNo">078</span>          ++existing.numWaiters;  // Add ourselves to waiters.<a name="line.78"></a>
-<span class="sourceLineNo">079</span>          while (existing.locked) {<a name="line.79"></a>
-<span class="sourceLineNo">080</span>            try {<a name="line.80"></a>
-<span class="sourceLineNo">081</span>              existing.wait();<a name="line.81"></a>
-<span class="sourceLineNo">082</span>            } catch (InterruptedException e) {<a name="line.82"></a>
-<span class="sourceLineNo">083</span>              --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.83"></a>
-<span class="sourceLineNo">084</span>              throw new InterruptedIOException(<a name="line.84"></a>
-<span class="sourceLineNo">085</span>                  "Interrupted waiting to acquire sparse lock");<a name="line.85"></a>
-<span class="sourceLineNo">086</span>            }<a name="line.86"></a>
-<span class="sourceLineNo">087</span>          }<a name="line.87"></a>
-<span class="sourceLineNo">088</span><a name="line.88"></a>
-<span class="sourceLineNo">089</span>          --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.89"></a>
-<span class="sourceLineNo">090</span>          existing.locked = true;<a name="line.90"></a>
-<span class="sourceLineNo">091</span>          return existing;<a name="line.91"></a>
-<span class="sourceLineNo">092</span>        }<a name="line.92"></a>
-<span class="sourceLineNo">093</span>        // If the entry is not locked, it might already be deleted from the<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        // map, so we cannot return it. We need to get our entry into the map<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        // or get someone else's locked entry.<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>    }<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    return entry;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  }<a name="line.99"></a>
-<span class="sourceLineNo">100</span><a name="line.100"></a>
-<span class="sourceLineNo">101</span>  /**<a name="line.101"></a>
-<span class="sourceLineNo">102</span>   * Must be called in a finally block to decrease the internal counter and<a name="line.102"></a>
-<span class="sourceLineNo">103</span>   * remove the monitor object for the given id if the caller is the last<a name="line.103"></a>
-<span class="sourceLineNo">104</span>   * client.<a name="line.104"></a>
-<span class="sourceLineNo">105</span>   *<a name="line.105"></a>
-<span class="sourceLineNo">106</span>   * @param entry the return value of {@link #getLockEntry(long)}<a name="line.106"></a>
-<span class="sourceLineNo">107</span>   */<a name="line.107"></a>
-<span class="sourceLineNo">108</span>  public void releaseLockEntry(Entry entry) {<a name="line.108"></a>
-<span class="sourceLineNo">109</span>    synchronized (entry) {<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      entry.locked = false;<a name="line.110"></a>
-<span class="sourceLineNo">111</span>      if (entry.numWaiters &gt; 0) {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>        entry.notify();<a name="line.112"></a>
-<span class="sourceLineNo">113</span>      } else {<a name="line.113"></a>
-<span class="sourceLineNo">114</span>        map.remove(entry.id);<a name="line.114"></a>
-<span class="sourceLineNo">115</span>      }<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><a name="line.118"></a>
-<span class="sourceLineNo">119</span>  /** For testing */<a name="line.119"></a>
-<span class="sourceLineNo">120</span>  void assertMapEmpty() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    assert map.isEmpty();<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  @VisibleForTesting<a name="line.124"></a>
-<span class="sourceLineNo">125</span>  public void waitForWaiters(long id, int numWaiters) throws InterruptedException {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    for (Entry entry;;) {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>      entry = map.get(id);<a name="line.127"></a>
-<span class="sourceLineNo">128</span>      if (entry != null) {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>        synchronized (entry) {<a name="line.129"></a>
-<span class="sourceLineNo">130</span>          if (entry.numWaiters &gt;= numWaiters) {<a name="line.130"></a>
-<span class="sourceLineNo">131</span>            return;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>          }<a name="line.132"></a>
-<span class="sourceLineNo">133</span>        }<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      }<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      Thread.sleep(100);<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    }<a name="line.136"></a>
-<span class="sourceLineNo">137</span>  }<a name="line.137"></a>
-<span class="sourceLineNo">138</span>}<a name="line.138"></a>
+<pre><span class="sourceLineNo">001</span>/**<a name="line.1"></a>
+<span class="sourceLineNo">002</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.2"></a>
+<span class="sourceLineNo">003</span> * or more contributor license agreements.  See the NOTICE file<a name="line.3"></a>
+<span class="sourceLineNo">004</span> * distributed with this work for additional information<a name="line.4"></a>
+<span class="sourceLineNo">005</span> * regarding copyright ownership.  The ASF licenses this file<a name="line.5"></a>
+<span class="sourceLineNo">006</span> * to you under the Apache License, Version 2.0 (the<a name="line.6"></a>
+<span class="sourceLineNo">007</span> * "License"); you may not use this file except in compliance<a name="line.7"></a>
+<span class="sourceLineNo">008</span> * with the License.  You may obtain a copy of the License at<a name="line.8"></a>
+<span class="sourceLineNo">009</span> *<a name="line.9"></a>
+<span class="sourceLineNo">010</span> *     http://www.apache.org/licenses/LICENSE-2.0<a name="line.10"></a>
+<span class="sourceLineNo">011</span> *<a name="line.11"></a>
+<span class="sourceLineNo">012</span> * Unless required by applicable law or agreed to in writing, software<a name="line.12"></a>
+<span class="sourceLineNo">013</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.13"></a>
+<span class="sourceLineNo">014</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.14"></a>
+<span class="sourceLineNo">015</span> * See the License for the specific language governing permissions and<a name="line.15"></a>
+<span class="sourceLineNo">016</span> * limitations under the License.<a name="line.16"></a>
+<span class="sourceLineNo">017</span> */<a name="line.17"></a>
+<span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.util;<a name="line.18"></a>
+<span class="sourceLineNo">019</span><a name="line.19"></a>
+<span class="sourceLineNo">020</span>import java.io.IOException;<a name="line.20"></a>
+<span class="sourceLineNo">021</span>import java.io.InterruptedIOException;<a name="line.21"></a>
+<span class="sourceLineNo">022</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.util.concurrent.ConcurrentMap;<a name="line.23"></a>
+<span class="sourceLineNo">024</span><a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.25"></a>
+<span class="sourceLineNo">026</span><a name="line.26"></a>
+<span class="sourceLineNo">027</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.27"></a>
+<span class="sourceLineNo">028</span><a name="line.28"></a>
+<span class="sourceLineNo">029</span>/**<a name="line.29"></a>
+<span class="sourceLineNo">030</span> * Allows multiple concurrent clients to lock on a numeric id with a minimal<a name="line.30"></a>
+<span class="sourceLineNo">031</span> * memory overhead. The intended usage is as follows:<a name="line.31"></a>
+<span class="sourceLineNo">032</span> *<a name="line.32"></a>
+<span class="sourceLineNo">033</span> * &lt;pre&gt;<a name="line.33"></a>
+<span class="sourceLineNo">034</span> * IdLock.Entry lockEntry = idLock.getLockEntry(id);<a name="line.34"></a>
+<span class="sourceLineNo">035</span> * try {<a name="line.35"></a>
+<span class="sourceLineNo">036</span> *   // User code.<a name="line.36"></a>
+<span class="sourceLineNo">037</span> * } finally {<a name="line.37"></a>
+<span class="sourceLineNo">038</span> *   idLock.releaseLockEntry(lockEntry);<a name="line.38"></a>
+<span class="sourceLineNo">039</span> * }&lt;/pre&gt;<a name="line.39"></a>
+<span class="sourceLineNo">040</span> */<a name="line.40"></a>
+<span class="sourceLineNo">041</span>@InterfaceAudience.Private<a name="line.41"></a>
+<span class="sourceLineNo">042</span>public class IdLock {<a name="line.42"></a>
+<span class="sourceLineNo">043</span><a name="line.43"></a>
+<span class="sourceLineNo">044</span>  /** An entry returned to the client as a lock object */<a name="line.44"></a>
+<span class="sourceLineNo">045</span>  public static final class Entry {<a name="line.45"></a>
+<span class="sourceLineNo">046</span>    private final long id;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>    private int numWaiters;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>    private boolean locked = true;<a name="line.48"></a>
+<span class="sourceLineNo">049</span><a name="line.49"></a>
+<span class="sourceLineNo">050</span>    private Entry(long id) {<a name="line.50"></a>
+<span class="sourceLineNo">051</span>      this.id = id;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>    }<a name="line.52"></a>
+<span class="sourceLineNo">053</span><a name="line.53"></a>
+<span class="sourceLineNo">054</span>    @Override<a name="line.54"></a>
+<span class="sourceLineNo">055</span>    public String toString() {<a name="line.55"></a>
+<span class="sourceLineNo">056</span>      return "id=" + id + ", numWaiter=" + numWaiters + ", isLocked="<a name="line.56"></a>
+<span class="sourceLineNo">057</span>          + locked;<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><a name="line.60"></a>
+<span class="sourceLineNo">061</span>  private ConcurrentMap&lt;Long, Entry&gt; map = new ConcurrentHashMap&lt;&gt;();<a name="line.61"></a>
+<span class="sourceLineNo">062</span><a name="line.62"></a>
+<span class="sourceLineNo">063</span>  /**<a name="line.63"></a>
+<span class="sourceLineNo">064</span>   * Blocks until the lock corresponding to the given id is acquired.<a name="line.64"></a>
+<span class="sourceLineNo">065</span>   *<a name="line.65"></a>
+<span class="sourceLineNo">066</span>   * @param id an arbitrary number to lock on<a name="line.66"></a>
+<span class="sourceLineNo">067</span>   * @return an "entry" to pass to {@link #releaseLockEntry(Entry)} to release<a name="line.67"></a>
+<span class="sourceLineNo">068</span>   *         the lock<a name="line.68"></a>
+<span class="sourceLineNo">069</span>   * @throws IOException if interrupted<a name="line.69"></a>
+<span class="sourceLineNo">070</span>   */<a name="line.70"></a>
+<span class="sourceLineNo">071</span>  public Entry getLockEntry(long id) throws IOException {<a name="line.71"></a>
+<span class="sourceLineNo">072</span>    Entry entry = new Entry(id);<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    Entry existing;<a name="line.73"></a>
+<span class="sourceLineNo">074</span>    while ((existing = map.putIfAbsent(entry.id, entry)) != null) {<a name="line.74"></a>
+<span class="sourceLineNo">075</span>      synchronized (existing) {<a name="line.75"></a>
+<span class="sourceLineNo">076</span>        if (existing.locked) {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>          ++existing.numWaiters;  // Add ourselves to waiters.<a name="line.77"></a>
+<span class="sourceLineNo">078</span>          while (existing.locked) {<a name="line.78"></a>
+<span class="sourceLineNo">079</span>            try {<a name="line.79"></a>
+<span class="sourceLineNo">080</span>              existing.wait();<a name="line.80"></a>
+<span class="sourceLineNo">081</span>            } catch (InterruptedException e) {<a name="line.81"></a>
+<span class="sourceLineNo">082</span>              --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.82"></a>
+<span class="sourceLineNo">083</span>              throw new InterruptedIOException(<a name="line.83"></a>
+<span class="sourceLineNo">084</span>                  "Interrupted waiting to acquire sparse lock");<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><a name="line.87"></a>
+<span class="sourceLineNo">088</span>          --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.88"></a>
+<span class="sourceLineNo">089</span>          existing.locked = true;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>          return existing;<a name="line.90"></a>
+<span class="sourceLineNo">091</span>        }<a name="line.91"></a>
+<span class="sourceLineNo">092</span>        // If the entry is not locked, it might already be deleted from the<a name="line.92"></a>
+<span class="sourceLineNo">093</span>        // map, so we cannot return it. We need to get our entry into the map<a name="line.93"></a>
+<span class="sourceLineNo">094</span>        // or get someone else's locked entry.<a name="line.94"></a>
+<span class="sourceLineNo">095</span>      }<a name="line.95"></a>
+<span class="sourceLineNo">096</span>    }<a name="line.96"></a>
+<span class="sourceLineNo">097</span>    return entry;<a name="line.97"></a>
+<span class="sourceLineNo">098</span>  }<a name="line.98"></a>
+<span class="sourceLineNo">099</span><a name="line.99"></a>
+<span class="sourceLineNo">100</span>  /**<a name="line.100"></a>
+<span class="sourceLineNo">101</span>   * Must be called in a finally block to decrease the internal counter and<a name="line.101"></a>
+<span class="sourceLineNo">102</span>   * remove the monitor object for the given id if the caller is the last<a name="line.102"></a>
+<span class="sourceLineNo">103</span>   * client.<a name="line.103"></a>
+<span class="sourceLineNo">104</span>   *<a name="line.104"></a>
+<span class="sourceLineNo">105</span>   * @param entry the return value of {@link #getLockEntry(long)}<a name="line.105"></a>
+<span class="sourceLineNo">106</span>   */<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  public void releaseLockEntry(Entry entry) {<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    synchronized (entry) {<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      entry.locked = false;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>      if (entry.numWaiters &gt; 0) {<a name="line.110"></a>
+<span class="sourceLineNo">111</span>        entry.notify();<a name="line.111"></a>
+<span class="sourceLineNo">112</span>      } else {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>        map.remove(entry.id);<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>  }<a name="line.116"></a>
+<span class="sourceLineNo">117</span><a name="line.117"></a>
+<span class="sourceLineNo">118</span>  /** For testing */<a name="line.118"></a>
+<span class="sourceLineNo">119</span>  void assertMapEmpty() {<a name="line.119"></a>
+<span class="sourceLineNo">120</span>    assert map.isEmpty();<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  }<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  @VisibleForTesting<a name="line.123"></a>
+<span class="sourceLineNo">124</span>  public void waitForWaiters(long id, int numWaiters) throws InterruptedException {<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    for (Entry entry;;) {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      entry = map.get(id);<a name="line.126"></a>
+<span class="sourceLineNo">127</span>      if (entry != null) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>        synchronized (entry) {<a name="line.128"></a>
+<span class="sourceLineNo">129</span>          if (entry.numWaiters &gt;= numWaiters) {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>            return;<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>      }<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      Thread.sleep(100);<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span>  }<a name="line.136"></a>
+<span class="sourceLineNo">137</span>}<a name="line.137"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.html b/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.html
index e3c9d73..18375e0 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/util/IdLock.html
@@ -6,144 +6,143 @@
 </head>
 <body>
 <div class="sourceContainer">
-<pre><span class="sourceLineNo">001</span>/*<a name="line.1"></a>
-<span class="sourceLineNo">002</span> *<a name="line.2"></a>
-<span class="sourceLineNo">003</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.3"></a>
-<span class="sourceLineNo">004</span> * or more contributor license agreements.  See the NOTICE file<a name="line.4"></a>
-<span class="sourceLineNo">005</span> * distributed with this work for additional information<a name="line.5"></a>
-<span class="sourceLineNo">006</span> * regarding copyright ownership.  The ASF licenses this file<a name="line.6"></a>
-<span class="sourceLineNo">007</span> * to you under the Apache License, Version 2.0 (the<a name="line.7"></a>
-<span class="sourceLineNo">008</span> * "License"); you may not use this file except in compliance<a name="line.8"></a>
-<span class="sourceLineNo">009</span> * with the License.  You may obtain a copy of the License at<a name="line.9"></a>
-<span class="sourceLineNo">010</span> *<a name="line.10"></a>
-<span class="sourceLineNo">011</span> *     http://www.apache.org/licenses/LICENSE-2.0<a name="line.11"></a>
-<span class="sourceLineNo">012</span> *<a name="line.12"></a>
-<span class="sourceLineNo">013</span> * Unless required by applicable law or agreed to in writing, software<a name="line.13"></a>
-<span class="sourceLineNo">014</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.14"></a>
-<span class="sourceLineNo">015</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.15"></a>
-<span class="sourceLineNo">016</span> * See the License for the specific language governing permissions and<a name="line.16"></a>
-<span class="sourceLineNo">017</span> * limitations under the License.<a name="line.17"></a>
-<span class="sourceLineNo">018</span> */<a name="line.18"></a>
-<span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.util;<a name="line.19"></a>
-<span class="sourceLineNo">020</span><a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.IOException;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import java.io.InterruptedIOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import java.util.concurrent.ConcurrentMap;<a name="line.24"></a>
-<span class="sourceLineNo">025</span><a name="line.25"></a>
-<span class="sourceLineNo">026</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.26"></a>
-<span class="sourceLineNo">027</span><a name="line.27"></a>
-<span class="sourceLineNo">028</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.28"></a>
-<span class="sourceLineNo">029</span><a name="line.29"></a>
-<span class="sourceLineNo">030</span>/**<a name="line.30"></a>
-<span class="sourceLineNo">031</span> * Allows multiple concurrent clients to lock on a numeric id with a minimal<a name="line.31"></a>
-<span class="sourceLineNo">032</span> * memory overhead. The intended usage is as follows:<a name="line.32"></a>
-<span class="sourceLineNo">033</span> *<a name="line.33"></a>
-<span class="sourceLineNo">034</span> * &lt;pre&gt;<a name="line.34"></a>
-<span class="sourceLineNo">035</span> * IdLock.Entry lockEntry = idLock.getLockEntry(id);<a name="line.35"></a>
-<span class="sourceLineNo">036</span> * try {<a name="line.36"></a>
-<span class="sourceLineNo">037</span> *   // User code.<a name="line.37"></a>
-<span class="sourceLineNo">038</span> * } finally {<a name="line.38"></a>
-<span class="sourceLineNo">039</span> *   idLock.releaseLockEntry(lockEntry);<a name="line.39"></a>
-<span class="sourceLineNo">040</span> * }&lt;/pre&gt;<a name="line.40"></a>
-<span class="sourceLineNo">041</span> */<a name="line.41"></a>
-<span class="sourceLineNo">042</span>@InterfaceAudience.Private<a name="line.42"></a>
-<span class="sourceLineNo">043</span>public class IdLock {<a name="line.43"></a>
-<span class="sourceLineNo">044</span><a name="line.44"></a>
-<span class="sourceLineNo">045</span>  /** An entry returned to the client as a lock object */<a name="line.45"></a>
-<span class="sourceLineNo">046</span>  public static class Entry {<a name="line.46"></a>
-<span class="sourceLineNo">047</span>    private final long id;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>    private int numWaiters;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>    private boolean locked = true;<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>    private Entry(long id) {<a name="line.51"></a>
-<span class="sourceLineNo">052</span>      this.id = id;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>    }<a name="line.53"></a>
-<span class="sourceLineNo">054</span><a name="line.54"></a>
-<span class="sourceLineNo">055</span>    @Override<a name="line.55"></a>
-<span class="sourceLineNo">056</span>    public String toString() {<a name="line.56"></a>
-<span class="sourceLineNo">057</span>      return "id=" + id + ", numWaiter=" + numWaiters + ", isLocked="<a name="line.57"></a>
-<span class="sourceLineNo">058</span>          + locked;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>    }<a name="line.59"></a>
-<span class="sourceLineNo">060</span>  }<a name="line.60"></a>
-<span class="sourceLineNo">061</span><a name="line.61"></a>
-<span class="sourceLineNo">062</span>  private ConcurrentMap&lt;Long, Entry&gt; map = new ConcurrentHashMap&lt;&gt;();<a name="line.62"></a>
-<span class="sourceLineNo">063</span><a name="line.63"></a>
-<span class="sourceLineNo">064</span>  /**<a name="line.64"></a>
-<span class="sourceLineNo">065</span>   * Blocks until the lock corresponding to the given id is acquired.<a name="line.65"></a>
-<span class="sourceLineNo">066</span>   *<a name="line.66"></a>
-<span class="sourceLineNo">067</span>   * @param id an arbitrary number to lock on<a name="line.67"></a>
-<span class="sourceLineNo">068</span>   * @return an "entry" to pass to {@link #releaseLockEntry(Entry)} to release<a name="line.68"></a>
-<span class="sourceLineNo">069</span>   *         the lock<a name="line.69"></a>
-<span class="sourceLineNo">070</span>   * @throws IOException if interrupted<a name="line.70"></a>
-<span class="sourceLineNo">071</span>   */<a name="line.71"></a>
-<span class="sourceLineNo">072</span>  public Entry getLockEntry(long id) throws IOException {<a name="line.72"></a>
-<span class="sourceLineNo">073</span>    Entry entry = new Entry(id);<a name="line.73"></a>
-<span class="sourceLineNo">074</span>    Entry existing;<a name="line.74"></a>
-<span class="sourceLineNo">075</span>    while ((existing = map.putIfAbsent(entry.id, entry)) != null) {<a name="line.75"></a>
-<span class="sourceLineNo">076</span>      synchronized (existing) {<a name="line.76"></a>
-<span class="sourceLineNo">077</span>        if (existing.locked) {<a name="line.77"></a>
-<span class="sourceLineNo">078</span>          ++existing.numWaiters;  // Add ourselves to waiters.<a name="line.78"></a>
-<span class="sourceLineNo">079</span>          while (existing.locked) {<a name="line.79"></a>
-<span class="sourceLineNo">080</span>            try {<a name="line.80"></a>
-<span class="sourceLineNo">081</span>              existing.wait();<a name="line.81"></a>
-<span class="sourceLineNo">082</span>            } catch (InterruptedException e) {<a name="line.82"></a>
-<span class="sourceLineNo">083</span>              --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.83"></a>
-<span class="sourceLineNo">084</span>              throw new InterruptedIOException(<a name="line.84"></a>
-<span class="sourceLineNo">085</span>                  "Interrupted waiting to acquire sparse lock");<a name="line.85"></a>
-<span class="sourceLineNo">086</span>            }<a name="line.86"></a>
-<span class="sourceLineNo">087</span>          }<a name="line.87"></a>
-<span class="sourceLineNo">088</span><a name="line.88"></a>
-<span class="sourceLineNo">089</span>          --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.89"></a>
-<span class="sourceLineNo">090</span>          existing.locked = true;<a name="line.90"></a>
-<span class="sourceLineNo">091</span>          return existing;<a name="line.91"></a>
-<span class="sourceLineNo">092</span>        }<a name="line.92"></a>
-<span class="sourceLineNo">093</span>        // If the entry is not locked, it might already be deleted from the<a name="line.93"></a>
-<span class="sourceLineNo">094</span>        // map, so we cannot return it. We need to get our entry into the map<a name="line.94"></a>
-<span class="sourceLineNo">095</span>        // or get someone else's locked entry.<a name="line.95"></a>
-<span class="sourceLineNo">096</span>      }<a name="line.96"></a>
-<span class="sourceLineNo">097</span>    }<a name="line.97"></a>
-<span class="sourceLineNo">098</span>    return entry;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  }<a name="line.99"></a>
-<span class="sourceLineNo">100</span><a name="line.100"></a>
-<span class="sourceLineNo">101</span>  /**<a name="line.101"></a>
-<span class="sourceLineNo">102</span>   * Must be called in a finally block to decrease the internal counter and<a name="line.102"></a>
-<span class="sourceLineNo">103</span>   * remove the monitor object for the given id if the caller is the last<a name="line.103"></a>
-<span class="sourceLineNo">104</span>   * client.<a name="line.104"></a>
-<span class="sourceLineNo">105</span>   *<a name="line.105"></a>
-<span class="sourceLineNo">106</span>   * @param entry the return value of {@link #getLockEntry(long)}<a name="line.106"></a>
-<span class="sourceLineNo">107</span>   */<a name="line.107"></a>
-<span class="sourceLineNo">108</span>  public void releaseLockEntry(Entry entry) {<a name="line.108"></a>
-<span class="sourceLineNo">109</span>    synchronized (entry) {<a name="line.109"></a>
-<span class="sourceLineNo">110</span>      entry.locked = false;<a name="line.110"></a>
-<span class="sourceLineNo">111</span>      if (entry.numWaiters &gt; 0) {<a name="line.111"></a>
-<span class="sourceLineNo">112</span>        entry.notify();<a name="line.112"></a>
-<span class="sourceLineNo">113</span>      } else {<a name="line.113"></a>
-<span class="sourceLineNo">114</span>        map.remove(entry.id);<a name="line.114"></a>
-<span class="sourceLineNo">115</span>      }<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><a name="line.118"></a>
-<span class="sourceLineNo">119</span>  /** For testing */<a name="line.119"></a>
-<span class="sourceLineNo">120</span>  void assertMapEmpty() {<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    assert map.isEmpty();<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  @VisibleForTesting<a name="line.124"></a>
-<span class="sourceLineNo">125</span>  public void waitForWaiters(long id, int numWaiters) throws InterruptedException {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    for (Entry entry;;) {<a name="line.126"></a>
-<span class="sourceLineNo">127</span>      entry = map.get(id);<a name="line.127"></a>
-<span class="sourceLineNo">128</span>      if (entry != null) {<a name="line.128"></a>
-<span class="sourceLineNo">129</span>        synchronized (entry) {<a name="line.129"></a>
-<span class="sourceLineNo">130</span>          if (entry.numWaiters &gt;= numWaiters) {<a name="line.130"></a>
-<span class="sourceLineNo">131</span>            return;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>          }<a name="line.132"></a>
-<span class="sourceLineNo">133</span>        }<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      }<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      Thread.sleep(100);<a name="line.135"></a>
-<span class="sourceLineNo">136</span>    }<a name="line.136"></a>
-<span class="sourceLineNo">137</span>  }<a name="line.137"></a>
-<span class="sourceLineNo">138</span>}<a name="line.138"></a>
+<pre><span class="sourceLineNo">001</span>/**<a name="line.1"></a>
+<span class="sourceLineNo">002</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.2"></a>
+<span class="sourceLineNo">003</span> * or more contributor license agreements.  See the NOTICE file<a name="line.3"></a>
+<span class="sourceLineNo">004</span> * distributed with this work for additional information<a name="line.4"></a>
+<span class="sourceLineNo">005</span> * regarding copyright ownership.  The ASF licenses this file<a name="line.5"></a>
+<span class="sourceLineNo">006</span> * to you under the Apache License, Version 2.0 (the<a name="line.6"></a>
+<span class="sourceLineNo">007</span> * "License"); you may not use this file except in compliance<a name="line.7"></a>
+<span class="sourceLineNo">008</span> * with the License.  You may obtain a copy of the License at<a name="line.8"></a>
+<span class="sourceLineNo">009</span> *<a name="line.9"></a>
+<span class="sourceLineNo">010</span> *     http://www.apache.org/licenses/LICENSE-2.0<a name="line.10"></a>
+<span class="sourceLineNo">011</span> *<a name="line.11"></a>
+<span class="sourceLineNo">012</span> * Unless required by applicable law or agreed to in writing, software<a name="line.12"></a>
+<span class="sourceLineNo">013</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.13"></a>
+<span class="sourceLineNo">014</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.14"></a>
+<span class="sourceLineNo">015</span> * See the License for the specific language governing permissions and<a name="line.15"></a>
+<span class="sourceLineNo">016</span> * limitations under the License.<a name="line.16"></a>
+<span class="sourceLineNo">017</span> */<a name="line.17"></a>
+<span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.util;<a name="line.18"></a>
+<span class="sourceLineNo">019</span><a name="line.19"></a>
+<span class="sourceLineNo">020</span>import java.io.IOException;<a name="line.20"></a>
+<span class="sourceLineNo">021</span>import java.io.InterruptedIOException;<a name="line.21"></a>
+<span class="sourceLineNo">022</span>import java.util.concurrent.ConcurrentHashMap;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.util.concurrent.ConcurrentMap;<a name="line.23"></a>
+<span class="sourceLineNo">024</span><a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.25"></a>
+<span class="sourceLineNo">026</span><a name="line.26"></a>
+<span class="sourceLineNo">027</span>import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;<a name="line.27"></a>
+<span class="sourceLineNo">028</span><a name="line.28"></a>
+<span class="sourceLineNo">029</span>/**<a name="line.29"></a>
+<span class="sourceLineNo">030</span> * Allows multiple concurrent clients to lock on a numeric id with a minimal<a name="line.30"></a>
+<span class="sourceLineNo">031</span> * memory overhead. The intended usage is as follows:<a name="line.31"></a>
+<span class="sourceLineNo">032</span> *<a name="line.32"></a>
+<span class="sourceLineNo">033</span> * &lt;pre&gt;<a name="line.33"></a>
+<span class="sourceLineNo">034</span> * IdLock.Entry lockEntry = idLock.getLockEntry(id);<a name="line.34"></a>
+<span class="sourceLineNo">035</span> * try {<a name="line.35"></a>
+<span class="sourceLineNo">036</span> *   // User code.<a name="line.36"></a>
+<span class="sourceLineNo">037</span> * } finally {<a name="line.37"></a>
+<span class="sourceLineNo">038</span> *   idLock.releaseLockEntry(lockEntry);<a name="line.38"></a>
+<span class="sourceLineNo">039</span> * }&lt;/pre&gt;<a name="line.39"></a>
+<span class="sourceLineNo">040</span> */<a name="line.40"></a>
+<span class="sourceLineNo">041</span>@InterfaceAudience.Private<a name="line.41"></a>
+<span class="sourceLineNo">042</span>public class IdLock {<a name="line.42"></a>
+<span class="sourceLineNo">043</span><a name="line.43"></a>
+<span class="sourceLineNo">044</span>  /** An entry returned to the client as a lock object */<a name="line.44"></a>
+<span class="sourceLineNo">045</span>  public static final class Entry {<a name="line.45"></a>
+<span class="sourceLineNo">046</span>    private final long id;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>    private int numWaiters;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>    private boolean locked = true;<a name="line.48"></a>
+<span class="sourceLineNo">049</span><a name="line.49"></a>
+<span class="sourceLineNo">050</span>    private Entry(long id) {<a name="line.50"></a>
+<span class="sourceLineNo">051</span>      this.id = id;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>    }<a name="line.52"></a>
+<span class="sourceLineNo">053</span><a name="line.53"></a>
+<span class="sourceLineNo">054</span>    @Override<a name="line.54"></a>
+<span class="sourceLineNo">055</span>    public String toString() {<a name="line.55"></a>
+<span class="sourceLineNo">056</span>      return "id=" + id + ", numWaiter=" + numWaiters + ", isLocked="<a name="line.56"></a>
+<span class="sourceLineNo">057</span>          + locked;<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><a name="line.60"></a>
+<span class="sourceLineNo">061</span>  private ConcurrentMap&lt;Long, Entry&gt; map = new ConcurrentHashMap&lt;&gt;();<a name="line.61"></a>
+<span class="sourceLineNo">062</span><a name="line.62"></a>
+<span class="sourceLineNo">063</span>  /**<a name="line.63"></a>
+<span class="sourceLineNo">064</span>   * Blocks until the lock corresponding to the given id is acquired.<a name="line.64"></a>
+<span class="sourceLineNo">065</span>   *<a name="line.65"></a>
+<span class="sourceLineNo">066</span>   * @param id an arbitrary number to lock on<a name="line.66"></a>
+<span class="sourceLineNo">067</span>   * @return an "entry" to pass to {@link #releaseLockEntry(Entry)} to release<a name="line.67"></a>
+<span class="sourceLineNo">068</span>   *         the lock<a name="line.68"></a>
+<span class="sourceLineNo">069</span>   * @throws IOException if interrupted<a name="line.69"></a>
+<span class="sourceLineNo">070</span>   */<a name="line.70"></a>
+<span class="sourceLineNo">071</span>  public Entry getLockEntry(long id) throws IOException {<a name="line.71"></a>
+<span class="sourceLineNo">072</span>    Entry entry = new Entry(id);<a name="line.72"></a>
+<span class="sourceLineNo">073</span>    Entry existing;<a name="line.73"></a>
+<span class="sourceLineNo">074</span>    while ((existing = map.putIfAbsent(entry.id, entry)) != null) {<a name="line.74"></a>
+<span class="sourceLineNo">075</span>      synchronized (existing) {<a name="line.75"></a>
+<span class="sourceLineNo">076</span>        if (existing.locked) {<a name="line.76"></a>
+<span class="sourceLineNo">077</span>          ++existing.numWaiters;  // Add ourselves to waiters.<a name="line.77"></a>
+<span class="sourceLineNo">078</span>          while (existing.locked) {<a name="line.78"></a>
+<span class="sourceLineNo">079</span>            try {<a name="line.79"></a>
+<span class="sourceLineNo">080</span>              existing.wait();<a name="line.80"></a>
+<span class="sourceLineNo">081</span>            } catch (InterruptedException e) {<a name="line.81"></a>
+<span class="sourceLineNo">082</span>              --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.82"></a>
+<span class="sourceLineNo">083</span>              throw new InterruptedIOException(<a name="line.83"></a>
+<span class="sourceLineNo">084</span>                  "Interrupted waiting to acquire sparse lock");<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><a name="line.87"></a>
+<span class="sourceLineNo">088</span>          --existing.numWaiters;  // Remove ourselves from waiters.<a name="line.88"></a>
+<span class="sourceLineNo">089</span>          existing.locked = true;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>          return existing;<a name="line.90"></a>
+<span class="sourceLineNo">091</span>        }<a name="line.91"></a>
+<span class="sourceLineNo">092</span>        // If the entry is not locked, it might already be deleted from the<a name="line.92"></a>
+<span class="sourceLineNo">093</span>        // map, so we cannot return it. We need to get our entry into the map<a name="line.93"></a>
+<span class="sourceLineNo">094</span>        // or get someone else's locked entry.<a name="line.94"></a>
+<span class="sourceLineNo">095</span>      }<a name="line.95"></a>
+<span class="sourceLineNo">096</span>    }<a name="line.96"></a>
+<span class="sourceLineNo">097</span>    return entry;<a name="line.97"></a>
+<span class="sourceLineNo">098</span>  }<a name="line.98"></a>
+<span class="sourceLineNo">099</span><a name="line.99"></a>
+<span class="sourceLineNo">100</span>  /**<a name="line.100"></a>
+<span class="sourceLineNo">101</span>   * Must be called in a finally block to decrease the internal counter and<a name="line.101"></a>
+<span class="sourceLineNo">102</span>   * remove the monitor object for the given id if the caller is the last<a name="line.102"></a>
+<span class="sourceLineNo">103</span>   * client.<a name="line.103"></a>
+<span class="sourceLineNo">104</span>   *<a name="line.104"></a>
+<span class="sourceLineNo">105</span>   * @param entry the return value of {@link #getLockEntry(long)}<a name="line.105"></a>
+<span class="sourceLineNo">106</span>   */<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  public void releaseLockEntry(Entry entry) {<a name="line.107"></a>
+<span class="sourceLineNo">108</span>    synchronized (entry) {<a name="line.108"></a>
+<span class="sourceLineNo">109</span>      entry.locked = false;<a name="line.109"></a>
+<span class="sourceLineNo">110</span>      if (entry.numWaiters &gt; 0) {<a name="line.110"></a>
+<span class="sourceLineNo">111</span>        entry.notify();<a name="line.111"></a>
+<span class="sourceLineNo">112</span>      } else {<a name="line.112"></a>
+<span class="sourceLineNo">113</span>        map.remove(entry.id);<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>  }<a name="line.116"></a>
+<span class="sourceLineNo">117</span><a name="line.117"></a>
+<span class="sourceLineNo">118</span>  /** For testing */<a name="line.118"></a>
+<span class="sourceLineNo">119</span>  void assertMapEmpty() {<a name="line.119"></a>
+<span class="sourceLineNo">120</span>    assert map.isEmpty();<a name="line.120"></a>
+<span class="sourceLineNo">121</span>  }<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  @VisibleForTesting<a name="line.123"></a>
+<span class="sourceLineNo">124</span>  public void waitForWaiters(long id, int numWaiters) throws InterruptedException {<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    for (Entry entry;;) {<a name="line.125"></a>
+<span class="sourceLineNo">126</span>      entry = map.get(id);<a name="line.126"></a>
+<span class="sourceLineNo">127</span>      if (entry != null) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>        synchronized (entry) {<a name="line.128"></a>
+<span class="sourceLineNo">129</span>          if (entry.numWaiters &gt;= numWaiters) {<a name="line.129"></a>
+<span class="sourceLineNo">130</span>            return;<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>      }<a name="line.133"></a>
+<span class="sourceLineNo">134</span>      Thread.sleep(100);<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    }<a name="line.135"></a>
+<span class="sourceLineNo">136</span>  }<a name="line.136"></a>
+<span class="sourceLineNo">137</span>}<a name="line.137"></a>
 
 
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/downloads.html
----------------------------------------------------------------------
diff --git a/downloads.html b/downloads.html
index 17aee59..5d23c3f 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBase Downloads</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -423,7 +423,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/export_control.html
----------------------------------------------------------------------
diff --git a/export_control.html b/export_control.html
index 9b072f4..2e7fed0 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Export Control
@@ -331,7 +331,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/index.html
----------------------------------------------------------------------
diff --git a/index.html b/index.html
index 942378d..0274fc4 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBase™ Home</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -411,7 +411,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/integration.html
----------------------------------------------------------------------
diff --git a/integration.html b/integration.html
index accd643..8f2d8af 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; CI Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -291,7 +291,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/issue-tracking.html
----------------------------------------------------------------------
diff --git a/issue-tracking.html b/issue-tracking.html
index 9ec0a71..b70f200 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Issue Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -288,7 +288,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/license.html
----------------------------------------------------------------------
diff --git a/license.html b/license.html
index cf5a2bf..4c53c7c 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Licenses</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -491,7 +491,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/mail-lists.html
----------------------------------------------------------------------
diff --git a/mail-lists.html b/mail-lists.html
index b5c11a0..b290e7b 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Mailing Lists</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/metrics.html
----------------------------------------------------------------------
diff --git a/metrics.html b/metrics.html
index 5bb9cc5..0d6fe09 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
       Apache HBase (TM) Metrics
@@ -459,7 +459,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/old_news.html
----------------------------------------------------------------------
diff --git a/old_news.html b/old_news.html
index e00984d..b1945d7 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Old Apache HBase (TM) News
@@ -440,7 +440,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/plugin-management.html
----------------------------------------------------------------------
diff --git a/plugin-management.html b/plugin-management.html
index 4004d15..3162676 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Plugin Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -440,7 +440,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/plugins.html
----------------------------------------------------------------------
diff --git a/plugins.html b/plugins.html
index 3892ffc..3a2264d 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Plugins</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -375,7 +375,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/poweredbyhbase.html
----------------------------------------------------------------------
diff --git a/poweredbyhbase.html b/poweredbyhbase.html
index a5f0c49..d643c1e 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <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.5-HBASE.min.css" />
@@ -769,7 +769,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/project-info.html
----------------------------------------------------------------------
diff --git a/project-info.html b/project-info.html
index c2a7db5..38610e6 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Information</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -335,7 +335,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/project-reports.html
----------------------------------------------------------------------
diff --git a/project-reports.html b/project-reports.html
index 5e4fc8c..a0d21e0 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Generated Reports</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -305,7 +305,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/project-summary.html
----------------------------------------------------------------------
diff --git a/project-summary.html b/project-summary.html
index 7149d65..1323dd7 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Summary</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -331,7 +331,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/pseudo-distributed.html
----------------------------------------------------------------------
diff --git a/pseudo-distributed.html b/pseudo-distributed.html
index 0ec71c7..da9666b 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013;  
 Running Apache HBase (TM) in pseudo-distributed mode
@@ -308,7 +308,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/replication.html
----------------------------------------------------------------------
diff --git a/replication.html b/replication.html
index 6c38eb3..99534af 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; 
       Apache HBase (TM) Replication
@@ -303,7 +303,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/resources.html
----------------------------------------------------------------------
diff --git a/resources.html b/resources.html
index b77c0ff..4916a26 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <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.5-HBASE.min.css" />
@@ -331,7 +331,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/source-repository.html
----------------------------------------------------------------------
diff --git a/source-repository.html b/source-repository.html
index 85529a4..cf93289 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Source Code Management</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -299,7 +299,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/sponsors.html
----------------------------------------------------------------------
diff --git a/sponsors.html b/sponsors.html
index fbe8905..ac58d4b 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Apache HBase™ Sponsors</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -333,7 +333,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/supportingprojects.html
----------------------------------------------------------------------
diff --git a/supportingprojects.html b/supportingprojects.html
index 63a9f66..1f84384 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Supporting Projects</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -520,7 +520,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-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>
 

http://git-wip-us.apache.org/repos/asf/hbase-site/blob/9cc58aff/team-list.html
----------------------------------------------------------------------
diff --git a/team-list.html b/team-list.html
index 2bbf451..7b9cd24 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="20180726" />
+    <meta name="Date-Revision-yyyymmdd" content="20180727" />
     <meta http-equiv="Content-Language" content="en" />
     <title>Apache HBase &#x2013; Project Team</title>
     <link rel="stylesheet" href="./css/apache-maven-fluido-1.5-HBASE.min.css" />
@@ -742,7 +742,7 @@
                         <a href="https://www.apache.org/">The Apache Software Foundation</a>.
             All rights reserved.      
                     
-                  <li id="publishDate" class="pull-right">Last Published: 2018-07-26</li>
+                  <li id="publishDate" class="pull-right">Last Published: 2018-07-27</li>
             </p>
                 </div>